aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorBlueWall2013-05-13 22:11:28 -0400
committerBlueWall2013-05-30 17:59:18 -0400
commit328883700a15e4216bf7b251ac099d38f413375e (patch)
treefc90ce9fe8f7b1c5caca393144eac5b2824a9f3a
parentminor: fix warnings in GodsModule that were due to duplicate using statements (diff)
downloadopensim-SC_OLD-328883700a15e4216bf7b251ac099d38f413375e.zip
opensim-SC_OLD-328883700a15e4216bf7b251ac099d38f413375e.tar.gz
opensim-SC_OLD-328883700a15e4216bf7b251ac099d38f413375e.tar.bz2
opensim-SC_OLD-328883700a15e4216bf7b251ac099d38f413375e.tar.xz
UserProfiles
UserProfiles for Robust and Standalone. Includes service and connectors for Robust and standalone opensim plus matching region module.
-rw-r--r--OpenSim/Data/IProfilesData.cs29
-rw-r--r--OpenSim/Data/MySQL/MySQLUserProfilesData.cs1023
-rw-r--r--OpenSim/Data/MySQL/Resources/UserProfiles.migrations83
-rw-r--r--OpenSim/Framework/UserProfiles.cs90
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs176
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs1386
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs226
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs1
-rw-r--r--OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs92
-rw-r--r--OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs434
-rw-r--r--OpenSim/Services/Interfaces/IUserProfilesService.cs48
-rw-r--r--OpenSim/Services/UserProfilesService/UserProfilesService.cs160
-rw-r--r--OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs59
-rw-r--r--bin/OpenSim.ini.example6
-rw-r--r--bin/OpenSimDefaults.ini13
-rw-r--r--bin/Robust.HG.ini.example12
-rw-r--r--bin/Robust.ini.example11
-rw-r--r--bin/config-include/StandaloneCommon.ini.example16
-rw-r--r--bin/config-include/StandaloneHypergrid.ini2
-rw-r--r--prebuild.xml38
20 files changed, 3727 insertions, 178 deletions
diff --git a/OpenSim/Data/IProfilesData.cs b/OpenSim/Data/IProfilesData.cs
new file mode 100644
index 0000000..eeccbf6
--- /dev/null
+++ b/OpenSim/Data/IProfilesData.cs
@@ -0,0 +1,29 @@
1using System;
2using OpenMetaverse;
3using OpenMetaverse.StructuredData;
4using OpenSim.Framework;
5
6namespace OpenSim.Data
7{
8
9 public interface IProfilesData
10 {
11 OSDArray GetClassifiedRecords(UUID creatorId);
12 bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result);
13 bool DeleteClassifiedRecord(UUID recordId);
14 OSDArray GetAvatarPicks(UUID avatarId);
15 UserProfilePick GetPickInfo(UUID avatarId, UUID pickId);
16 bool UpdatePicksRecord(UserProfilePick pick);
17 bool DeletePicksRecord(UUID pickId);
18 bool GetAvatarNotes(ref UserProfileNotes note);
19 bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result);
20 bool GetAvatarProperties(ref UserProfileProperties props, ref string result);
21 bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
22 bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
23 bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
24 bool GetUserAppData(ref UserAppData props, ref string result);
25 bool SetUserAppData(UserAppData props, ref string result);
26 OSDArray GetUserImageAssets(UUID avatarId);
27 }
28}
29
diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
new file mode 100644
index 0000000..09bd448
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
@@ -0,0 +1,1023 @@
1using System;
2using System.Data;
3using System.Reflection;
4using OpenSim.Data;
5using OpenSim.Framework;
6using MySql.Data.MySqlClient;
7using OpenMetaverse;
8using OpenMetaverse.StructuredData;
9using log4net;
10
11namespace OpenSim.Data.MySQL
12{
13 public class UserProfilesData: IProfilesData
14 {
15 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
16
17 #region Properites
18 string ConnectionString
19 {
20 get; set;
21 }
22
23 protected object Lock
24 {
25 get; set;
26 }
27
28 protected virtual Assembly Assembly
29 {
30 get { return GetType().Assembly; }
31 }
32
33 #endregion Properties
34
35 #region class Member Functions
36 public UserProfilesData(string connectionString)
37 {
38 ConnectionString = connectionString;
39 Init();
40 }
41
42 void Init()
43 {
44 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
45 {
46 dbcon.Open();
47
48 Migration m = new Migration(dbcon, Assembly, "UserProfiles");
49 m.Update();
50 }
51 }
52 #endregion Member Functions
53
54 #region Classifieds Queries
55 /// <summary>
56 /// Gets the classified records.
57 /// </summary>
58 /// <returns>
59 /// Array of classified records
60 /// </returns>
61 /// <param name='creatorId'>
62 /// Creator identifier.
63 /// </param>
64 public OSDArray GetClassifiedRecords(UUID creatorId)
65 {
66 OSDArray data = new OSDArray();
67
68 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
69 {
70 string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id";
71 dbcon.Open();
72 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
73 {
74 cmd.Parameters.AddWithValue("?Id", creatorId);
75 using( MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
76 {
77 if(reader.HasRows)
78 {
79 while (reader.Read())
80 {
81 OSDMap n = new OSDMap();
82 UUID Id = UUID.Zero;
83
84 string Name = null;
85 try
86 {
87 UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id);
88 Name = Convert.ToString(reader["name"]);
89 }
90 catch (Exception e)
91 {
92 m_log.DebugFormat("[PROFILES_DATA]" +
93 ": UserAccount exception {0}", e.Message);
94 }
95 n.Add("classifieduuid", OSD.FromUUID(Id));
96 n.Add("name", OSD.FromString(Name));
97 data.Add(n);
98 }
99 }
100 }
101 }
102 }
103 return data;
104 }
105
106 public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result)
107 {
108 string query = string.Empty;
109
110
111 query += "INSERT INTO classifieds (";
112 query += "`classifieduuid`,";
113 query += "`creatoruuid`,";
114 query += "`creationdate`,";
115 query += "`expirationdate`,";
116 query += "`category`,";
117 query += "`name`,";
118 query += "`description`,";
119 query += "`parceluuid`,";
120 query += "`parentestate`,";
121 query += "`snapshotuuid`,";
122 query += "`simname`,";
123 query += "`posglobal`,";
124 query += "`parcelname`,";
125 query += "`classifiedflags`,";
126 query += "`priceforlisting`) ";
127 query += "VALUES (";
128 query += "?ClassifiedId,";
129 query += "?CreatorId,";
130 query += "?CreatedDate,";
131 query += "?ExpirationDate,";
132 query += "?Category,";
133 query += "?Name,";
134 query += "?Description,";
135 query += "?ParcelId,";
136 query += "?ParentEstate,";
137 query += "?SnapshotId,";
138 query += "?SimName,";
139 query += "?GlobalPos,";
140 query += "?ParcelName,";
141 query += "?Flags,";
142 query += "?ListingPrice ) ";
143 query += "ON DUPLICATE KEY UPDATE ";
144 query += "category=?Category, ";
145 query += "expirationdate=?ExpirationDate, ";
146 query += "name=?Name, ";
147 query += "description=?Description, ";
148 query += "parentestate=?ParentEstate, ";
149 query += "posglobal=?GlobalPos, ";
150 query += "parcelname=?ParcelName, ";
151 query += "classifiedflags=?Flags, ";
152 query += "priceforlisting=?ListingPrice, ";
153 query += "snapshotuuid=?SnapshotId";
154
155 if(string.IsNullOrEmpty(ad.ParcelName))
156 ad.ParcelName = "Unknown";
157 if(ad.ParcelId == null)
158 ad.ParcelId = UUID.Zero;
159 if(string.IsNullOrEmpty(ad.Description))
160 ad.Description = "No Description";
161
162 DateTime epoch = new DateTime(1970, 1, 1);
163 DateTime now = DateTime.Now;
164 TimeSpan epochnow = now - epoch;
165 TimeSpan duration;
166 DateTime expiration;
167 TimeSpan epochexp;
168
169 if(ad.Flags == 2)
170 {
171 duration = new TimeSpan(7,0,0,0);
172 expiration = now.Add(duration);
173 epochexp = expiration - epoch;
174 }
175 else
176 {
177 duration = new TimeSpan(365,0,0,0);
178 expiration = now.Add(duration);
179 epochexp = expiration - epoch;
180 }
181 ad.CreationDate = (int)epochnow.TotalSeconds;
182 ad.ExpirationDate = (int)epochexp.TotalSeconds;
183
184 try
185 {
186 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
187 {
188 dbcon.Open();
189 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
190 {
191 cmd.Parameters.AddWithValue("?ClassifiedId", ad.ClassifiedId.ToString());
192 cmd.Parameters.AddWithValue("?CreatorId", ad.CreatorId.ToString());
193 cmd.Parameters.AddWithValue("?CreatedDate", ad.CreationDate.ToString());
194 cmd.Parameters.AddWithValue("?ExpirationDate", ad.ExpirationDate.ToString());
195 cmd.Parameters.AddWithValue("?Category", ad.Category.ToString());
196 cmd.Parameters.AddWithValue("?Name", ad.Name.ToString());
197 cmd.Parameters.AddWithValue("?Description", ad.Description.ToString());
198 cmd.Parameters.AddWithValue("?ParcelId", ad.ParcelId.ToString());
199 cmd.Parameters.AddWithValue("?ParentEstate", ad.ParentEstate.ToString());
200 cmd.Parameters.AddWithValue("?SnapshotId", ad.SnapshotId.ToString ());
201 cmd.Parameters.AddWithValue("?SimName", ad.SimName.ToString());
202 cmd.Parameters.AddWithValue("?GlobalPos", ad.GlobalPos.ToString());
203 cmd.Parameters.AddWithValue("?ParcelName", ad.ParcelName.ToString());
204 cmd.Parameters.AddWithValue("?Flags", ad.Flags.ToString());
205 cmd.Parameters.AddWithValue("?ListingPrice", ad.Price.ToString ());
206
207 cmd.ExecuteNonQuery();
208 }
209 }
210 }
211 catch (Exception e)
212 {
213 m_log.DebugFormat("[PROFILES_DATA]" +
214 ": ClassifiedesUpdate exception {0}", e.Message);
215 result = e.Message;
216 return false;
217 }
218 return true;
219 }
220
221 public bool DeleteClassifiedRecord(UUID recordId)
222 {
223 string query = string.Empty;
224
225 query += "DELETE FROM classifieds WHERE ";
226 query += "classifieduuid = ?ClasifiedId";
227
228 try
229 {
230 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
231 {
232 dbcon.Open();
233
234 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
235 {
236 cmd.Parameters.AddWithValue("?ClassifiedId", recordId.ToString());
237
238 lock(Lock)
239 {
240 cmd.ExecuteNonQuery();
241 }
242 }
243 }
244 }
245 catch (Exception e)
246 {
247 m_log.DebugFormat("[PROFILES_DATA]" +
248 ": DeleteClassifiedRecord exception {0}", e.Message);
249 return false;
250 }
251 return true;
252 }
253
254 public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result)
255 {
256 string query = string.Empty;
257
258 query += "SELECT * FROM classifieds WHERE ";
259 query += "classifieduuid = ?AdId";
260
261 try
262 {
263 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
264 {
265 dbcon.Open();
266 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
267 {
268 cmd.Parameters.AddWithValue("?AdId", ad.ClassifiedId.ToString());
269
270 using (MySqlDataReader reader = cmd.ExecuteReader())
271 {
272 if(reader.Read ())
273 {
274 ad.CreatorId = new UUID(reader.GetGuid("creatoruuid"));
275 ad.ParcelId = new UUID(reader.GetGuid("parceluuid"));
276 ad.SnapshotId = new UUID(reader.GetGuid("snapshotuuid"));
277 ad.CreationDate = Convert.ToInt32(reader["creationdate"]);
278 ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]);
279 ad.ParentEstate = Convert.ToInt32(reader["parentestate"]);
280 ad.Flags = (byte)reader.GetUInt32("classifiedflags");
281 ad.Category = reader.GetInt32("category");
282 ad.Price = reader.GetInt16("priceforlisting");
283 ad.Name = reader.GetString("name");
284 ad.Description = reader.GetString("description");
285 ad.SimName = reader.GetString("simname");
286 ad.GlobalPos = reader.GetString("posglobal");
287 ad.ParcelName = reader.GetString("parcelname");
288
289 }
290 }
291 }
292 dbcon.Close();
293 }
294 }
295 catch (Exception e)
296 {
297 m_log.DebugFormat("[PROFILES_DATA]" +
298 ": GetPickInfo exception {0}", e.Message);
299 }
300 return true;
301 }
302 #endregion Classifieds Queries
303
304 #region Picks Queries
305 public OSDArray GetAvatarPicks(UUID avatarId)
306 {
307 string query = string.Empty;
308
309 query += "SELECT `pickuuid`,`name` FROM userpicks WHERE ";
310 query += "creatoruuid = ?Id";
311 OSDArray data = new OSDArray();
312
313 try
314 {
315 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
316 {
317 dbcon.Open();
318 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
319 {
320 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
321
322 using (MySqlDataReader reader = cmd.ExecuteReader())
323 {
324 if(reader.HasRows)
325 {
326 while (reader.Read())
327 {
328 OSDMap record = new OSDMap();
329
330 record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"]));
331 record.Add("name",OSD.FromString((string)reader["name"]));
332 data.Add(record);
333 }
334 }
335 }
336 }
337 }
338 }
339 catch (Exception e)
340 {
341 m_log.DebugFormat("[PROFILES_DATA]" +
342 ": GetAvatarPicks exception {0}", e.Message);
343 }
344 return data;
345 }
346
347 public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId)
348 {
349 string query = string.Empty;
350 UserProfilePick pick = new UserProfilePick();
351
352 query += "SELECT * FROM userpicks WHERE ";
353 query += "creatoruuid = ?CreatorId AND ";
354 query += "pickuuid = ?PickId";
355
356 try
357 {
358 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
359 {
360 dbcon.Open();
361 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
362 {
363 cmd.Parameters.AddWithValue("?CreatorId", avatarId.ToString());
364 cmd.Parameters.AddWithValue("?PickId", pickId.ToString());
365
366 using (MySqlDataReader reader = cmd.ExecuteReader())
367 {
368 if(reader.HasRows)
369 {
370 reader.Read();
371
372 string description = (string)reader["description"];
373
374 if (string.IsNullOrEmpty(description))
375 description = "No description given.";
376
377 UUID.TryParse((string)reader["pickuuid"], out pick.PickId);
378 UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId);
379 UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
380 UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
381 pick.GlobalPos = (string)reader["posglobal"];
382 bool.TryParse((string)reader["toppick"], out pick.TopPick);
383 bool.TryParse((string)reader["enabled"], out pick.Enabled);
384 pick.Name = (string)reader["name"];
385 pick.Desc = description;
386 pick.User = (string)reader["user"];
387 pick.OriginalName = (string)reader["originalname"];
388 pick.SimName = (string)reader["simname"];
389 pick.SortOrder = (int)reader["sortorder"];
390 }
391 }
392 }
393 dbcon.Close();
394 }
395 }
396 catch (Exception e)
397 {
398 m_log.DebugFormat("[PROFILES_DATA]" +
399 ": GetPickInfo exception {0}", e.Message);
400 }
401 return pick;
402 }
403
404 public bool UpdatePicksRecord(UserProfilePick pick)
405 {
406 string query = string.Empty;
407
408 query += "INSERT INTO userpicks VALUES (";
409 query += "?PickId,";
410 query += "?CreatorId,";
411 query += "?TopPick,";
412 query += "?ParcelId,";
413 query += "?Name,";
414 query += "?Desc,";
415 query += "?SnapshotId,";
416 query += "?User,";
417 query += "?Original,";
418 query += "?SimName,";
419 query += "?GlobalPos,";
420 query += "?SortOrder,";
421 query += "?Enabled) ";
422 query += "ON DUPLICATE KEY UPDATE ";
423 query += "parceluuid=?ParcelId,";
424 query += "name=?Name,";
425 query += "description=?Desc,";
426 query += "snapshotuuid=?SnapshotId,";
427 query += "pickuuid=?PickId,";
428 query += "posglobal=?GlobalPos";
429
430 try
431 {
432 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
433 {
434 dbcon.Open();
435 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
436 {
437 cmd.Parameters.AddWithValue("?PickId", pick.PickId.ToString());
438 cmd.Parameters.AddWithValue("?CreatorId", pick.CreatorId.ToString());
439 cmd.Parameters.AddWithValue("?TopPick", pick.TopPick.ToString());
440 cmd.Parameters.AddWithValue("?ParcelId", pick.ParcelId.ToString());
441 cmd.Parameters.AddWithValue("?Name", pick.Name.ToString());
442 cmd.Parameters.AddWithValue("?Desc", pick.Desc.ToString());
443 cmd.Parameters.AddWithValue("?SnapshotId", pick.SnapshotId.ToString());
444 cmd.Parameters.AddWithValue("?User", pick.User.ToString());
445 cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString());
446 cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString());
447 cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos);
448 cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ());
449 cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString());
450
451 cmd.ExecuteNonQuery();
452 }
453 }
454 }
455 catch (Exception e)
456 {
457 m_log.DebugFormat("[PROFILES_DATA]" +
458 ": UpdateAvatarNotes exception {0}", e.Message);
459 return false;
460 }
461 return true;
462 }
463
464 public bool DeletePicksRecord(UUID pickId)
465 {
466 string query = string.Empty;
467
468 query += "DELETE FROM userpicks WHERE ";
469 query += "pickuuid = ?PickId";
470
471 try
472 {
473 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
474 {
475 dbcon.Open();
476
477 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
478 {
479 cmd.Parameters.AddWithValue("?PickId", pickId.ToString());
480
481 cmd.ExecuteNonQuery();
482 }
483 }
484 }
485 catch (Exception e)
486 {
487 m_log.DebugFormat("[PROFILES_DATA]" +
488 ": DeleteUserPickRecord exception {0}", e.Message);
489 return false;
490 }
491 return true;
492 }
493 #endregion Picks Queries
494
495 #region Avatar Notes Queries
496 public bool GetAvatarNotes(ref UserProfileNotes notes)
497 { // WIP
498 string query = string.Empty;
499
500 query += "SELECT `notes` FROM usernotes WHERE ";
501 query += "useruuid = ?Id AND ";
502 query += "targetuuid = ?TargetId";
503 OSDArray data = new OSDArray();
504
505 try
506 {
507 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
508 {
509 dbcon.Open();
510 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
511 {
512 cmd.Parameters.AddWithValue("?Id", notes.UserId.ToString());
513 cmd.Parameters.AddWithValue("?TargetId", notes.TargetId.ToString());
514
515 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
516 {
517 if(reader.HasRows)
518 {
519 reader.Read();
520 notes.Notes = OSD.FromString((string)reader["notes"]);
521 }
522 }
523 }
524 }
525 }
526 catch (Exception e)
527 {
528 m_log.DebugFormat("[PROFILES_DATA]" +
529 ": GetAvatarNotes exception {0}", e.Message);
530 }
531 return true;
532 }
533
534 public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result)
535 {
536 string query = string.Empty;
537 bool remove;
538
539 if(string.IsNullOrEmpty(note.Notes))
540 {
541 remove = true;
542 query += "DELETE FROM usernotes WHERE ";
543 query += "useruuid=?UserId AND ";
544 query += "targetuuid=?TargetId";
545 }
546 else
547 {
548 remove = false;
549 query += "INSERT INTO usernotes VALUES ( ";
550 query += "?UserId,";
551 query += "?TargetId,";
552 query += "?Notes )";
553 query += "ON DUPLICATE KEY ";
554 query += "UPDATE ";
555 query += "notes=?Notes";
556 }
557
558 try
559 {
560 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
561 {
562 dbcon.Open();
563 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
564 {
565 if(!remove)
566 cmd.Parameters.AddWithValue("?Notes", note.Notes);
567 cmd.Parameters.AddWithValue("?TargetId", note.TargetId.ToString ());
568 cmd.Parameters.AddWithValue("?UserId", note.UserId.ToString());
569
570 cmd.ExecuteNonQuery();
571 }
572 }
573 }
574 catch (Exception e)
575 {
576 m_log.DebugFormat("[PROFILES_DATA]" +
577 ": UpdateAvatarNotes exception {0}", e.Message);
578 return false;
579 }
580 return true;
581
582 }
583 #endregion Avatar Notes Queries
584
585 #region Avatar Properties
586 public bool GetAvatarProperties(ref UserProfileProperties props, ref string result)
587 {
588 string query = string.Empty;
589
590 query += "SELECT * FROM userprofile WHERE ";
591 query += "useruuid = ?Id";
592
593 try
594 {
595 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
596 {
597 dbcon.Open();
598 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
599 {
600 cmd.Parameters.AddWithValue("?Id", props.UserId.ToString());
601
602 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
603 {
604 if(reader.HasRows)
605 {
606 m_log.DebugFormat("[PROFILES_DATA]" +
607 ": Getting data for {0}.", props.UserId);
608 reader.Read();
609 props.WebUrl = (string)reader["profileURL"];
610 UUID.TryParse((string)reader["profileImage"], out props.ImageId);
611 props.AboutText = (string)reader["profileAboutText"];
612 UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId);
613 props.FirstLifeText = (string)reader["profileFirstText"];
614 UUID.TryParse((string)reader["profilePartner"], out props.PartnerId);
615 props.WantToMask = (int)reader["profileWantToMask"];
616 props.WantToText = (string)reader["profileWantToText"];
617 props.SkillsMask = (int)reader["profileSkillsMask"];
618 props.SkillsText = (string)reader["profileSkillsText"];
619 props.Language = (string)reader["profileLanguages"];
620 }
621 else
622 {
623 m_log.DebugFormat("[PROFILES_DATA]" +
624 ": No data for {0}", props.UserId);
625
626 props.WebUrl = string.Empty;
627 props.ImageId = UUID.Zero;
628 props.AboutText = string.Empty;
629 props.FirstLifeImageId = UUID.Zero;
630 props.FirstLifeText = string.Empty;
631 props.PartnerId = UUID.Zero;
632 props.WantToMask = 0;
633 props.WantToText = string.Empty;
634 props.SkillsMask = 0;
635 props.SkillsText = string.Empty;
636 props.Language = string.Empty;
637
638 query = "INSERT INTO userprofile (`useruuid`) VALUES (?userId)";
639
640 dbcon.Close();
641 dbcon.Open();
642
643 using (MySqlCommand put = new MySqlCommand(query, dbcon))
644 {
645 put.Parameters.AddWithValue("?userId", props.UserId.ToString());
646 put.ExecuteNonQuery();
647 }
648 }
649 }
650 }
651 }
652 }
653 catch (Exception e)
654 {
655 m_log.DebugFormat("[PROFILES_DATA]" +
656 ": Requst properties exception {0}", e.Message);
657 result = e.Message;
658 return false;
659 }
660 return true;
661 }
662
663 public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result)
664 {
665 string query = string.Empty;
666
667 query += "UPDATE userprofile SET ";
668 query += "profileURL=?profileURL, ";
669 query += "profileImage=?image, ";
670 query += "profileAboutText=?abouttext,";
671 query += "profileFirstImage=?firstlifeimage,";
672 query += "profileFirstText=?firstlifetext ";
673 query += "WHERE useruuid=?uuid";
674
675 try
676 {
677 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
678 {
679 dbcon.Open();
680 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
681 {
682 cmd.Parameters.AddWithValue("?profileURL", props.WebUrl);
683 cmd.Parameters.AddWithValue("?image", props.ImageId.ToString());
684 cmd.Parameters.AddWithValue("?abouttext", props.AboutText);
685 cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString());
686 cmd.Parameters.AddWithValue("?firstlifetext", props.FirstLifeText);
687 cmd.Parameters.AddWithValue("?uuid", props.UserId.ToString());
688
689 cmd.ExecuteNonQuery();
690 }
691 }
692 }
693 catch (Exception e)
694 {
695 m_log.DebugFormat("[PROFILES_DATA]" +
696 ": AgentPropertiesUpdate exception {0}", e.Message);
697
698 return false;
699 }
700 return true;
701 }
702 #endregion Avatar Properties
703
704 #region Avatar Interests
705 public bool UpdateAvatarInterests(UserProfileProperties up, ref string result)
706 {
707 string query = string.Empty;
708
709 query += "UPDATE userprofile SET ";
710 query += "profileWantToMask=?WantMask, ";
711 query += "profileWantToText=?WantText,";
712 query += "profileSkillsMask=?SkillsMask,";
713 query += "profileSkillsText=?SkillsText, ";
714 query += "profileLanguages=?Languages ";
715 query += "WHERE useruuid=?uuid";
716
717 try
718 {
719 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
720 {
721 dbcon.Open();
722 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
723 {
724 cmd.Parameters.AddWithValue("?WantMask", up.WantToMask);
725 cmd.Parameters.AddWithValue("?WantText", up.WantToText);
726 cmd.Parameters.AddWithValue("?SkillsMask", up.SkillsMask);
727 cmd.Parameters.AddWithValue("?SkillsText", up.SkillsText);
728 cmd.Parameters.AddWithValue("?Languages", up.Language);
729 cmd.Parameters.AddWithValue("?uuid", up.UserId.ToString());
730
731 cmd.ExecuteNonQuery();
732 }
733 }
734 }
735 catch (Exception e)
736 {
737 m_log.DebugFormat("[PROFILES_DATA]" +
738 ": AgentInterestsUpdate exception {0}", e.Message);
739 result = e.Message;
740 return false;
741 }
742 return true;
743 }
744 #endregion Avatar Interests
745
746 public OSDArray GetUserImageAssets(UUID avatarId)
747 {
748 OSDArray data = new OSDArray();
749 string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id";
750
751 // Get classified image assets
752
753
754 try
755 {
756 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
757 {
758 dbcon.Open();
759
760 using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`classifieds`"), dbcon))
761 {
762 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
763
764 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
765 {
766 if(reader.HasRows)
767 {
768 while (reader.Read())
769 {
770 data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
771 }
772 }
773 }
774 }
775
776 dbcon.Close();
777 dbcon.Open();
778
779 using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon))
780 {
781 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
782
783 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
784 {
785 if(reader.HasRows)
786 {
787 while (reader.Read())
788 {
789 data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
790 }
791 }
792 }
793 }
794
795 dbcon.Close();
796 dbcon.Open();
797
798 query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id";
799
800 using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon))
801 {
802 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
803
804 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
805 {
806 if(reader.HasRows)
807 {
808 while (reader.Read())
809 {
810 data.Add(new OSDString((string)reader["profileImage"].ToString ()));
811 data.Add(new OSDString((string)reader["profileFirstImage"].ToString ()));
812 }
813 }
814 }
815 }
816 }
817 }
818 catch (Exception e)
819 {
820 m_log.DebugFormat("[PROFILES_DATA]" +
821 ": GetAvatarNotes exception {0}", e.Message);
822 }
823 return data;
824 }
825
826 #region User Preferences
827 public OSDArray GetUserPreferences(UUID avatarId)
828 {
829 string query = string.Empty;
830
831 query += "SELECT imviaemail,visible,email FROM ";
832 query += "usersettings WHERE ";
833 query += "useruuid = ?Id";
834
835 OSDArray data = new OSDArray();
836
837 try
838 {
839 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
840 {
841 dbcon.Open();
842 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
843 {
844 cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
845
846 using (MySqlDataReader reader = cmd.ExecuteReader())
847 {
848 if(reader.HasRows)
849 {
850 reader.Read();
851 OSDMap record = new OSDMap();
852
853 record.Add("imviaemail",OSD.FromString((string)reader["imviaemail"]));
854 record.Add("visible",OSD.FromString((string)reader["visible"]));
855 record.Add("email",OSD.FromString((string)reader["email"]));
856 data.Add(record);
857 }
858 else
859 {
860 using (MySqlCommand put = new MySqlCommand(query, dbcon))
861 {
862 query = "INSERT INTO usersettings VALUES ";
863 query += "(?Id,'false','false', '')";
864
865 lock(Lock)
866 {
867 put.ExecuteNonQuery();
868 }
869 }
870 }
871 }
872 }
873 }
874 }
875 catch (Exception e)
876 {
877 m_log.DebugFormat("[PROFILES_DATA]" +
878 ": Get preferences exception {0}", e.Message);
879 }
880 return data;
881 }
882
883 public bool UpdateUserPreferences(bool emailIm, bool visible, UUID avatarId )
884 {
885 string query = string.Empty;
886
887 query += "UPDATE userpsettings SET ";
888 query += "imviaemail=?ImViaEmail, ";
889 query += "visible=?Visible,";
890 query += "WHERE useruuid=?uuid";
891
892 try
893 {
894 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
895 {
896 dbcon.Open();
897 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
898 {
899 cmd.Parameters.AddWithValue("?ImViaEmail", emailIm.ToString().ToLower ());
900 cmd.Parameters.AddWithValue("?WantText", visible.ToString().ToLower ());
901 cmd.Parameters.AddWithValue("?uuid", avatarId.ToString());
902
903 lock(Lock)
904 {
905 cmd.ExecuteNonQuery();
906 }
907 }
908 }
909 }
910 catch (Exception e)
911 {
912 m_log.DebugFormat("[PROFILES_DATA]" +
913 ": AgentInterestsUpdate exception {0}", e.Message);
914 return false;
915 }
916 return true;
917 }
918 #endregion User Preferences
919
920 #region Integration
921 public bool GetUserAppData(ref UserAppData props, ref string result)
922 {
923 string query = string.Empty;
924
925 query += "SELECT * FROM `userdata` WHERE ";
926 query += "UserId = ?Id AND ";
927 query += "TagId = ?TagId";
928
929 try
930 {
931 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
932 {
933 dbcon.Open();
934 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
935 {
936 cmd.Parameters.AddWithValue("?Id", props.UserId.ToString());
937 cmd.Parameters.AddWithValue ("?TagId", props.TagId.ToString());
938
939 using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
940 {
941 if(reader.HasRows)
942 {
943 reader.Read();
944 props.DataKey = (string)reader["DataKey"];
945 props.DataVal = (string)reader["DataVal"];
946 }
947 else
948 {
949 query += "INSERT INTO userdata VALUES ( ";
950 query += "?UserId,";
951 query += "?TagId,";
952 query += "?DataKey,";
953 query += "?DataVal) ";
954
955 using (MySqlCommand put = new MySqlCommand(query, dbcon))
956 {
957 put.Parameters.AddWithValue("?Id", props.UserId.ToString());
958 put.Parameters.AddWithValue("?TagId", props.TagId.ToString());
959 put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
960 put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString());
961
962 lock(Lock)
963 {
964 put.ExecuteNonQuery();
965 }
966 }
967 }
968 }
969 }
970 }
971 }
972 catch (Exception e)
973 {
974 m_log.DebugFormat("[PROFILES_DATA]" +
975 ": Requst application data exception {0}", e.Message);
976 result = e.Message;
977 return false;
978 }
979 return true;
980 }
981
982 public bool SetUserAppData(UserAppData props, ref string result)
983 {
984 string query = string.Empty;
985
986 query += "UPDATE userdata SET ";
987 query += "TagId = ?TagId, ";
988 query += "DataKey = ?DataKey, ";
989 query += "DataVal = ?DataVal WHERE ";
990 query += "UserId = ?UserId AND ";
991 query += "TagId = ?TagId";
992
993 try
994 {
995 using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
996 {
997 dbcon.Open();
998 using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
999 {
1000 cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString());
1001 cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString ());
1002 cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString ());
1003 cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString ());
1004
1005 lock(Lock)
1006 {
1007 cmd.ExecuteNonQuery();
1008 }
1009 }
1010 }
1011 }
1012 catch (Exception e)
1013 {
1014 m_log.DebugFormat("[PROFILES_DATA]" +
1015 ": SetUserData exception {0}", e.Message);
1016 return false;
1017 }
1018 return true;
1019 }
1020 #endregion Integration
1021 }
1022}
1023
diff --git a/OpenSim/Data/MySQL/Resources/UserProfiles.migrations b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations
new file mode 100644
index 0000000..c29f1ab
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/UserProfiles.migrations
@@ -0,0 +1,83 @@
1:VERSION 1 # -------------------------------
2
3begin;
4
5CREATE TABLE IF NOT EXISTS `classifieds` (
6 `classifieduuid` char(36) NOT NULL,
7 `creatoruuid` char(36) NOT NULL,
8 `creationdate` int(20) NOT NULL,
9 `expirationdate` int(20) NOT NULL,
10 `category` varchar(20) NOT NULL,
11 `name` varchar(255) NOT NULL,
12 `description` text NOT NULL,
13 `parceluuid` char(36) NOT NULL,
14 `parentestate` int(11) NOT NULL,
15 `snapshotuuid` char(36) NOT NULL,
16 `simname` varchar(255) NOT NULL,
17 `posglobal` varchar(255) NOT NULL,
18 `parcelname` varchar(255) NOT NULL,
19 `classifiedflags` int(8) NOT NULL,
20 `priceforlisting` int(5) NOT NULL,
21 PRIMARY KEY (`classifieduuid`)
22) ENGINE=InnoDB DEFAULT CHARSET=latin1;
23
24
25CREATE TABLE IF NOT EXISTS `usernotes` (
26 `useruuid` varchar(36) NOT NULL,
27 `targetuuid` varchar(36) NOT NULL,
28 `notes` text NOT NULL,
29 UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`)
30) ENGINE=MyISAM DEFAULT CHARSET=latin1;
31
32
33CREATE TABLE IF NOT EXISTS `userpicks` (
34 `pickuuid` varchar(36) NOT NULL,
35 `creatoruuid` varchar(36) NOT NULL,
36 `toppick` enum('true','false') NOT NULL,
37 `parceluuid` varchar(36) NOT NULL,
38 `name` varchar(255) NOT NULL,
39 `description` text NOT NULL,
40 `snapshotuuid` varchar(36) NOT NULL,
41 `user` varchar(255) NOT NULL,
42 `originalname` varchar(255) NOT NULL,
43 `simname` varchar(255) NOT NULL,
44 `posglobal` varchar(255) NOT NULL,
45 `sortorder` int(2) NOT NULL,
46 `enabled` enum('true','false') NOT NULL,
47 PRIMARY KEY (`pickuuid`)
48) ENGINE=MyISAM DEFAULT CHARSET=latin1;
49
50
51CREATE TABLE IF NOT EXISTS `userprofile` (
52 `useruuid` varchar(36) NOT NULL,
53 `profilePartner` varchar(36) NOT NULL,
54 `profileAllowPublish` binary(1) NOT NULL,
55 `profileMaturePublish` binary(1) NOT NULL,
56 `profileURL` varchar(255) NOT NULL,
57 `profileWantToMask` int(3) NOT NULL,
58 `profileWantToText` text NOT NULL,
59 `profileSkillsMask` int(3) NOT NULL,
60 `profileSkillsText` text NOT NULL,
61 `profileLanguages` text NOT NULL,
62 `profileImage` varchar(36) NOT NULL,
63 `profileAboutText` text NOT NULL,
64 `profileFirstImage` varchar(36) NOT NULL,
65 `profileFirstText` text NOT NULL,
66 PRIMARY KEY (`useruuid`)
67) ENGINE=MyISAM DEFAULT CHARSET=latin1;
68
69commit;
70
71:VERSION 2 # -------------------------------
72
73begin;
74CREATE TABLE IF NOT EXISTS `userdata` (
75 `UserId` char(36) NOT NULL,
76 `TagId` varchar(64) NOT NULL,
77 `DataKey` varchar(255),
78 `DataVal` varchar(255),
79 PRIMARY KEY (`UserId`,`TagId`)
80) ENGINE=MyISAM DEFAULT CHARSET=latin1;
81
82commit;
83
diff --git a/OpenSim/Framework/UserProfiles.cs b/OpenSim/Framework/UserProfiles.cs
new file mode 100644
index 0000000..aabbb84
--- /dev/null
+++ b/OpenSim/Framework/UserProfiles.cs
@@ -0,0 +1,90 @@
1using System;
2using OpenMetaverse;
3
4namespace OpenSim.Framework
5{
6 public class UserClassifiedAdd
7 {
8 public UUID ClassifiedId = UUID.Zero;
9 public UUID CreatorId = UUID.Zero;
10 public int CreationDate = 0;
11 public int ExpirationDate = 0;
12 public int Category = 0;
13 public string Name = string.Empty;
14 public string Description = string.Empty;
15 public UUID ParcelId = UUID.Zero;
16 public int ParentEstate = 0;
17 public UUID SnapshotId = UUID.Zero;
18 public string SimName = string.Empty;
19 public string GlobalPos = "<0,0,0>";
20 public string ParcelName = string.Empty;
21 public byte Flags = 0;
22 public int Price = 0;
23 }
24
25 public class UserProfileProperties
26 {
27 public UUID UserId = UUID.Zero;
28 public UUID PartnerId = UUID.Zero;
29 public bool PublishProfile = false;
30 public bool PublishMature = false;
31 public string WebUrl = string.Empty;
32 public int WantToMask = 0;
33 public string WantToText = string.Empty;
34 public int SkillsMask = 0;
35 public string SkillsText = string.Empty;
36 public string Language = string.Empty;
37 public UUID ImageId = UUID.Zero;
38 public string AboutText = string.Empty;
39 public UUID FirstLifeImageId = UUID.Zero;
40 public string FirstLifeText = string.Empty;
41 }
42
43 public class UserProfilePick
44 {
45 public UUID PickId = UUID.Zero;
46 public UUID CreatorId = UUID.Zero;
47 public bool TopPick = false;
48 public string Name = string.Empty;
49 public string OriginalName = string.Empty;
50 public string Desc = string.Empty;
51 public UUID ParcelId = UUID.Zero;
52 public UUID SnapshotId = UUID.Zero;
53 public string User = string.Empty;
54 public string SimName = string.Empty;
55 public string GlobalPos = "<0,0,0>";
56 public int SortOrder = 0;
57 public bool Enabled = false;
58 }
59
60 public class UserProfileNotes
61 {
62 public UUID UserId;
63 public UUID TargetId;
64 public string Notes;
65 }
66
67 public class UserAccountProperties
68 {
69 public string EmailAddress = string.Empty;
70 public string Firstname = string.Empty;
71 public string LastName = string.Empty;
72 public string Password = string.Empty;
73 public string UserId = string.Empty;
74 }
75
76 public class UserAccountAuth
77 {
78 public string UserId = UUID.Zero.ToString();
79 public string Password = string.Empty;
80 }
81
82 public class UserAppData
83 {
84 public string TagId = string.Empty;
85 public string DataKey = string.Empty;
86 public string UserId = UUID.Zero.ToString();
87 public string DataVal = string.Empty;
88 }
89}
90
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
deleted file mode 100644
index bf24030..0000000
--- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
+++ /dev/null
@@ -1,176 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Globalization;
31using System.Reflection;
32
33using OpenMetaverse;
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37
38using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Region.CoreModules.Avatar.Profile
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicProfileModule")]
46 public class BasicProfileModule : IProfileModule, ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //
51 // Module vars
52 //
53 private List<Scene> m_Scenes = new List<Scene>();
54 private bool m_Enabled = false;
55
56 #region ISharedRegionModule
57
58 public void Initialise(IConfigSource config)
59 {
60 m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
61 m_Enabled = true;
62 }
63
64 public void AddRegion(Scene scene)
65 {
66 if (!m_Enabled)
67 return;
68
69 lock (m_Scenes)
70 {
71 if (!m_Scenes.Contains(scene))
72 {
73 m_Scenes.Add(scene);
74 // Hook up events
75 scene.EventManager.OnNewClient += OnNewClient;
76 scene.RegisterModuleInterface<IProfileModule>(this);
77 }
78 }
79 }
80
81 public void RegionLoaded(Scene scene)
82 {
83 if (!m_Enabled)
84 return;
85 }
86
87 public void RemoveRegion(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91
92 lock (m_Scenes)
93 {
94 m_Scenes.Remove(scene);
95 }
96 }
97
98 public void PostInitialise()
99 {
100 }
101
102 public void Close()
103 {
104 }
105
106 public string Name
107 {
108 get { return "BasicProfileModule"; }
109 }
110
111 public Type ReplaceableInterface
112 {
113 get { return typeof(IProfileModule); }
114 }
115
116 #endregion
117
118 /// New Client Event Handler
119 private void OnNewClient(IClientAPI client)
120 {
121 //Profile
122 client.OnRequestAvatarProperties += RequestAvatarProperties;
123 }
124
125 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
126 {
127 IScene s = remoteClient.Scene;
128 if (!(s is Scene))
129 return;
130
131// Scene scene = (Scene)s;
132
133 string profileUrl = String.Empty;
134 string aboutText = String.Empty;
135 string firstLifeAboutText = String.Empty;
136 UUID image = UUID.Zero;
137 UUID firstLifeImage = UUID.Zero;
138 UUID partner = UUID.Zero;
139 uint wantMask = 0;
140 string wantText = String.Empty;
141 uint skillsMask = 0;
142 string skillsText = String.Empty;
143 string languages = String.Empty;
144
145 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, avatarID);
146
147 string name = "Avatar";
148 int created = 0;
149 if (account != null)
150 {
151 name = account.FirstName + " " + account.LastName;
152 created = account.Created;
153 }
154 Byte[] charterMember = Utils.StringToBytes(name);
155
156 profileUrl = "No profile data";
157 aboutText = string.Empty;
158 firstLifeAboutText = string.Empty;
159 image = UUID.Zero;
160 firstLifeImage = UUID.Zero;
161 partner = UUID.Zero;
162
163 remoteClient.SendAvatarProperties(avatarID, aboutText,
164 Util.ToDateTime(created).ToString(
165 "M/d/yyyy", CultureInfo.InvariantCulture),
166 charterMember, firstLifeAboutText,
167 (uint)(0 & 0xff),
168 firstLifeImage, image, profileUrl, partner);
169
170 //Viewer expects interest data when it asks for properties.
171 remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
172 skillsMask, skillsText, languages);
173 }
174
175 }
176}
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
new file mode 100644
index 0000000..563617d
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -0,0 +1,1386 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Text;
31using System.Collections;
32using System.Collections.Generic;
33using System.Globalization;
34using System.Net;
35using System.Net.Sockets;
36using System.Reflection;
37using System.Xml;
38using OpenMetaverse;
39using OpenMetaverse.StructuredData;
40using log4net;
41using Nini.Config;
42using Nwc.XmlRpc;
43using OpenSim.Framework;
44using OpenSim.Region.Framework.Interfaces;
45using OpenSim.Region.Framework.Scenes;
46using OpenSim.Services.Interfaces;
47using Mono.Addins;
48using OpenSim.Services.Connectors.Hypergrid;
49
50namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
51{
52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")]
53 public class UserProfileModule : IProfileModule, INonSharedRegionModule
54 {
55 /// <summary>
56 /// Logging
57 /// </summary>
58 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
60 // The pair of Dictionaries are used to handle the switching of classified ads
61 // by maintaining a cache of classified id to creator id mappings and an interest
62 // count. The entries are removed when the interest count reaches 0.
63 Dictionary<UUID,UUID> classifiedCache = new Dictionary<UUID, UUID>();
64 Dictionary<UUID,int> classifiedInterest = new Dictionary<UUID, int>();
65
66 public Scene Scene
67 {
68 get; private set;
69 }
70
71 /// <summary>
72 /// Gets or sets the ConfigSource.
73 /// </summary>
74 /// <value>
75 /// The configuration
76 /// </value>
77 public IConfigSource Config {
78 get;
79 set;
80 }
81
82 /// <summary>
83 /// Gets or sets the URI to the profile server.
84 /// </summary>
85 /// <value>
86 /// The profile server URI.
87 /// </value>
88 public string ProfileServerUri {
89 get;
90 set;
91 }
92
93 IProfileModule ProfileModule
94 {
95 get; set;
96 }
97
98 IUserManagement UserManagementModule
99 {
100 get; set;
101 }
102
103 /// <summary>
104 /// Gets or sets a value indicating whether this
105 /// <see cref="BlueWall.SlipStream.ProfileModule.UserProfileModule"/> is enabled.
106 /// </summary>
107 /// <value>
108 /// <c>true</c> if enabled; otherwise, <c>false</c>.
109 /// </value>
110 public bool Enabled {
111 get;
112 set;
113 }
114
115 #region IRegionModuleBase implementation
116 /// <summary>
117 /// This is called to initialize the region module. For shared modules, this is called exactly once, after
118 /// creating the single (shared) instance. For non-shared modules, this is called once on each instance, after
119 /// the instace for the region has been created.
120 /// </summary>
121 /// <param name='source'>
122 /// Source.
123 /// </param>
124 public void Initialise(IConfigSource source)
125 {
126 Config = source;
127
128 IConfig profileConfig = Config.Configs["Profile"];
129
130 if (profileConfig == null)
131 {
132 Enabled = false;
133 return;
134 }
135
136 // If we find ProfileURL then we configure for FULL support
137 // else we setup for BASIC support
138 ProfileServerUri = profileConfig.GetString("ProfileURL", "");
139 if (ProfileServerUri == "")
140 {
141 m_log.Info("[PROFILES] UserProfiles module is activated in BASIC mode");
142 Enabled = false;
143 return;
144 }
145 else
146 {
147 m_log.Info("[PROFILES] UserProfiles module is activated in FULL mode");
148 Enabled = true;
149 }
150 }
151
152 /// <summary>
153 /// Adds the region.
154 /// </summary>
155 /// <param name='scene'>
156 /// Scene.
157 /// </param>
158 public void AddRegion(Scene scene)
159 {
160 Scene = scene;
161 Scene.RegisterModuleInterface<IProfileModule>(this);
162 Scene.EventManager.OnNewClient += OnNewClient;
163 Scene.EventManager.OnMakeRootAgent += HandleOnMakeRootAgent;
164
165 UserManagementModule = Scene.RequestModuleInterface<IUserManagement>();
166 }
167
168 void HandleOnMakeRootAgent (ScenePresence obj)
169 {
170 GetImageAssets(((IScenePresence)obj).UUID);
171 }
172
173 /// <summary>
174 /// Removes the region.
175 /// </summary>
176 /// <param name='scene'>
177 /// Scene.
178 /// </param>
179 public void RemoveRegion(Scene scene)
180 {
181 }
182
183 /// <summary>
184 /// This will be called once for every scene loaded. In a shared module this will be multiple times in one
185 /// instance, while a nonshared module instance will only be called once. This method is called after AddRegion
186 /// has been called in all modules for that scene, providing an opportunity to request another module's
187 /// interface, or hook an event from another module.
188 /// </summary>
189 /// <param name='scene'>
190 /// Scene.
191 /// </param>
192 public void RegionLoaded(Scene scene)
193 {
194 }
195
196 /// <summary>
197 /// If this returns non-null, it is the type of an interface that this module intends to register. This will
198 /// cause the loader to defer loading of this module until all other modules have been loaded. If no other
199 /// module has registered the interface by then, this module will be activated, else it will remain inactive,
200 /// letting the other module take over. This should return non-null ONLY in modules that are intended to be
201 /// easily replaceable, e.g. stub implementations that the developer expects to be replaced by third party
202 /// provided modules.
203 /// </summary>
204 /// <value>
205 /// The replaceable interface.
206 /// </value>
207 public Type ReplaceableInterface
208 {
209 get { return typeof(IProfileModule); }
210 }
211
212 /// <summary>
213 /// Called as the instance is closed.
214 /// </summary>
215 public void Close()
216 {
217 }
218
219 /// <value>
220 /// The name of the module
221 /// </value>
222 /// <summary>
223 /// Gets the module name.
224 /// </summary>
225 public string Name
226 {
227 get { return "UserProfileModule"; }
228 }
229 #endregion IRegionModuleBase implementation
230
231 #region Region Event Handlers
232 /// <summary>
233 /// Raises the new client event.
234 /// </summary>
235 /// <param name='client'>
236 /// Client.
237 /// </param>
238 void OnNewClient(IClientAPI client)
239 {
240 // Basic or Full module?
241 if(!Enabled)
242 {
243 client.OnRequestAvatarProperties += BasicRequestProperties;
244 return;
245 }
246
247 //Profile
248 client.OnRequestAvatarProperties += RequestAvatarProperties;
249 client.OnUpdateAvatarProperties += AvatarPropertiesUpdate;
250 client.OnAvatarInterestUpdate += AvatarInterestsUpdate;
251
252 // Classifieds
253 client.AddGenericPacketHandler("avatarclassifiedsrequest", ClassifiedsRequest);
254 client.OnClassifiedInfoUpdate += ClassifiedInfoUpdate;
255 client.OnClassifiedInfoRequest += ClassifiedInfoRequest;
256 client.OnClassifiedDelete += ClassifiedDelete;
257
258 // Picks
259 client.AddGenericPacketHandler("avatarpicksrequest", PicksRequest);
260 client.AddGenericPacketHandler("pickinforequest", PickInfoRequest);
261 client.OnPickInfoUpdate += PickInfoUpdate;
262 client.OnPickDelete += PickDelete;
263
264 // Notes
265 client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest);
266 client.OnAvatarNotesUpdate += NotesUpdate;
267 }
268 #endregion Region Event Handlers
269
270 #region Classified
271 ///
272 /// <summary>
273 /// Handles the avatar classifieds request.
274 /// </summary>
275 /// <param name='sender'>
276 /// Sender.
277 /// </param>
278 /// <param name='method'>
279 /// Method.
280 /// </param>
281 /// <param name='args'>
282 /// Arguments.
283 /// </param>
284 public void ClassifiedsRequest(Object sender, string method, List<String> args)
285 {
286 if (!(sender is IClientAPI))
287 return;
288
289 IClientAPI remoteClient = (IClientAPI)sender;
290
291 UUID targetID;
292 UUID.TryParse(args[0], out targetID);
293
294 // Can't handle NPC yet...
295 ScenePresence p = FindPresence(targetID);
296
297 if (null != p)
298 {
299 if (p.PresenceType == PresenceType.Npc)
300 return;
301 }
302
303 string serverURI = string.Empty;
304 bool foreign = GetUserProfileServerURI(targetID, out serverURI);
305 UUID creatorId = UUID.Zero;
306
307 OSDMap parameters= new OSDMap();
308 UUID.TryParse(args[0], out creatorId);
309 parameters.Add("creatorId", OSD.FromUUID(creatorId));
310 OSD Params = (OSD)parameters;
311 if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString()))
312 {
313 // Error Handling here!
314 // if(parameters.ContainsKey("message")
315 }
316
317 parameters = (OSDMap)Params;
318
319 OSDArray list = (OSDArray)parameters["result"];
320
321 Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>();
322
323 foreach(OSD map in list)
324 {
325 OSDMap m = (OSDMap)map;
326 UUID cid = m["classifieduuid"].AsUUID();
327 string name = m["name"].AsString();
328
329 classifieds[cid] = name;
330
331 if(!classifiedCache.ContainsKey(cid))
332 {
333 classifiedCache.Add(cid,creatorId);
334 classifiedInterest.Add(cid, 0);
335 }
336
337 classifiedInterest[cid] ++;
338 }
339
340 remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds);
341 }
342
343 public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient)
344 {
345 UUID target = remoteClient.AgentId;
346 UserClassifiedAdd ad = new UserClassifiedAdd();
347 ad.ClassifiedId = queryClassifiedID;
348
349 if(classifiedCache.ContainsKey(queryClassifiedID))
350 {
351 target = classifiedCache[queryClassifiedID];
352
353 if(classifiedInterest[queryClassifiedID] -- == 0)
354 {
355 lock(classifiedCache)
356 {
357 lock(classifiedInterest)
358 {
359 classifiedInterest.Remove(queryClassifiedID);
360 }
361 classifiedCache.Remove(queryClassifiedID);
362 }
363 }
364 }
365
366
367 string serverURI = string.Empty;
368 bool foreign = GetUserProfileServerURI(target, out serverURI);
369
370 object Ad = (object)ad;
371 if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString()))
372 {
373 remoteClient.SendAgentAlertMessage(
374 "Error getting classified info", false);
375 return;
376 }
377 ad = (UserClassifiedAdd) Ad;
378
379 if(ad.CreatorId == UUID.Zero)
380 return;
381
382 Vector3 globalPos = new Vector3();
383 Vector3.TryParse(ad.GlobalPos, out globalPos);
384
385 remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate, (uint)ad.ExpirationDate,
386 (uint)ad.Category, ad.Name, ad.Description, ad.ParcelId, (uint)ad.ParentEstate,
387 ad.SnapshotId, ad.SimName, globalPos, ad.ParcelName, ad.Flags, ad.Price);
388
389 }
390
391 /// <summary>
392 /// Classifieds info update.
393 /// </summary>
394 /// <param name='queryclassifiedID'>
395 /// Queryclassified I.
396 /// </param>
397 /// <param name='queryCategory'>
398 /// Query category.
399 /// </param>
400 /// <param name='queryName'>
401 /// Query name.
402 /// </param>
403 /// <param name='queryDescription'>
404 /// Query description.
405 /// </param>
406 /// <param name='queryParcelID'>
407 /// Query parcel I.
408 /// </param>
409 /// <param name='queryParentEstate'>
410 /// Query parent estate.
411 /// </param>
412 /// <param name='querySnapshotID'>
413 /// Query snapshot I.
414 /// </param>
415 /// <param name='queryGlobalPos'>
416 /// Query global position.
417 /// </param>
418 /// <param name='queryclassifiedFlags'>
419 /// Queryclassified flags.
420 /// </param>
421 /// <param name='queryclassifiedPrice'>
422 /// Queryclassified price.
423 /// </param>
424 /// <param name='remoteClient'>
425 /// Remote client.
426 /// </param>
427 public void ClassifiedInfoUpdate(UUID queryclassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID,
428 uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags,
429 int queryclassifiedPrice, IClientAPI remoteClient)
430 {
431 UserClassifiedAdd ad = new UserClassifiedAdd();
432
433 Scene s = (Scene) remoteClient.Scene;
434 Vector3 pos = remoteClient.SceneAgent.AbsolutePosition;
435 ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y);
436 ScenePresence p = FindPresence(remoteClient.AgentId);
437 Vector3 avaPos = p.AbsolutePosition;
438
439 string serverURI = string.Empty;
440 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
441
442 if (land == null)
443 {
444 ad.ParcelName = string.Empty;
445 }
446 else
447 {
448 ad.ParcelName = land.LandData.Name;
449 }
450
451 ad.CreatorId = remoteClient.AgentId;
452 ad.ClassifiedId = queryclassifiedID;
453 ad.Category = Convert.ToInt32(queryCategory);
454 ad.Name = queryName;
455 ad.Description = queryDescription;
456 ad.ParentEstate = Convert.ToInt32(queryParentEstate);
457 ad.SnapshotId = querySnapshotID;
458 ad.SimName = remoteClient.Scene.RegionInfo.RegionName;
459 ad.GlobalPos = queryGlobalPos.ToString ();
460 ad.Flags = queryclassifiedFlags;
461 ad.Price = queryclassifiedPrice;
462 ad.ParcelId = p.currentParcelUUID;
463
464 object Ad = ad;
465
466 OSD X = OSD.SerializeMembers(Ad);
467
468 if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString()))
469 {
470 remoteClient.SendAgentAlertMessage(
471 "Error updating classified", false);
472 }
473 }
474
475 /// <summary>
476 /// Classifieds delete.
477 /// </summary>
478 /// <param name='queryClassifiedID'>
479 /// Query classified I.
480 /// </param>
481 /// <param name='remoteClient'>
482 /// Remote client.
483 /// </param>
484 public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient)
485 {
486 string serverURI = string.Empty;
487 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
488
489 UUID classifiedId;
490 OSDMap parameters= new OSDMap();
491 UUID.TryParse(queryClassifiedID.ToString(), out classifiedId);
492 parameters.Add("classifiedId", OSD.FromUUID(classifiedId));
493 OSD Params = (OSD)parameters;
494 if(!JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString()))
495 {
496 remoteClient.SendAgentAlertMessage(
497 "Error classified delete", false);
498 }
499
500 parameters = (OSDMap)Params;
501 }
502 #endregion Classified
503
504 #region Picks
505 /// <summary>
506 /// Handles the avatar picks request.
507 /// </summary>
508 /// <param name='sender'>
509 /// Sender.
510 /// </param>
511 /// <param name='method'>
512 /// Method.
513 /// </param>
514 /// <param name='args'>
515 /// Arguments.
516 /// </param>
517 public void PicksRequest(Object sender, string method, List<String> args)
518 {
519 if (!(sender is IClientAPI))
520 return;
521
522 IClientAPI remoteClient = (IClientAPI)sender;
523
524 UUID targetId;
525 UUID.TryParse(args[0], out targetId);
526
527 // Can't handle NPC yet...
528 ScenePresence p = FindPresence(targetId);
529
530 if (null != p)
531 {
532 if (p.PresenceType == PresenceType.Npc)
533 return;
534 }
535
536 string serverURI = string.Empty;
537 bool foreign = GetUserProfileServerURI(targetId, out serverURI);
538
539 OSDMap parameters= new OSDMap();
540 parameters.Add("creatorId", OSD.FromUUID(targetId));
541 OSD Params = (OSD)parameters;
542 if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString()))
543 {
544 remoteClient.SendAgentAlertMessage(
545 "Error requesting picks", false);
546 return;
547 }
548
549 parameters = (OSDMap)Params;
550
551 OSDArray list = (OSDArray)parameters["result"];
552
553 Dictionary<UUID, string> picks = new Dictionary<UUID, string>();
554
555 foreach(OSD map in list)
556 {
557 OSDMap m = (OSDMap)map;
558 UUID cid = m["pickuuid"].AsUUID();
559 string name = m["name"].AsString();
560
561 m_log.DebugFormat("[PROFILES]: PicksRequest {0}", name);
562
563 picks[cid] = name;
564 }
565 remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks);
566 }
567
568 /// <summary>
569 /// Handles the pick info request.
570 /// </summary>
571 /// <param name='sender'>
572 /// Sender.
573 /// </param>
574 /// <param name='method'>
575 /// Method.
576 /// </param>
577 /// <param name='args'>
578 /// Arguments.
579 /// </param>
580 public void PickInfoRequest(Object sender, string method, List<String> args)
581 {
582 if (!(sender is IClientAPI))
583 return;
584
585 UUID targetID;
586 UUID.TryParse(args[0], out targetID);
587 string serverURI = string.Empty;
588 bool foreign = GetUserProfileServerURI(targetID, out serverURI);
589 IClientAPI remoteClient = (IClientAPI)sender;
590
591 UserProfilePick pick = new UserProfilePick();
592 UUID.TryParse(args[0], out pick.CreatorId);
593 UUID.TryParse(args[1], out pick.PickId);
594
595
596 object Pick = (object)pick;
597 if(!JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString()))
598 {
599 remoteClient.SendAgentAlertMessage(
600 "Error selecting pick", false);
601 }
602 pick = (UserProfilePick) Pick;
603 if(pick.SnapshotId == UUID.Zero)
604 {
605 // In case of a new UserPick, the data may not be ready and we would send wrong data, skip it...
606 m_log.DebugFormat("[PROFILES]: PickInfoRequest: SnapshotID is {0}", UUID.Zero.ToString());
607 return;
608 }
609
610 Vector3 globalPos;
611 Vector3.TryParse(pick.GlobalPos,out globalPos);
612
613 m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
614
615 remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
616 pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName,
617 globalPos,pick.SortOrder,pick.Enabled);
618 }
619
620 /// <summary>
621 /// Updates the userpicks
622 /// </summary>
623 /// <param name='remoteClient'>
624 /// Remote client.
625 /// </param>
626 /// <param name='pickID'>
627 /// Pick I.
628 /// </param>
629 /// <param name='creatorID'>
630 /// the creator of the pick
631 /// </param>
632 /// <param name='topPick'>
633 /// Top pick.
634 /// </param>
635 /// <param name='name'>
636 /// Name.
637 /// </param>
638 /// <param name='desc'>
639 /// Desc.
640 /// </param>
641 /// <param name='snapshotID'>
642 /// Snapshot I.
643 /// </param>
644 /// <param name='sortOrder'>
645 /// Sort order.
646 /// </param>
647 /// <param name='enabled'>
648 /// Enabled.
649 /// </param>
650 public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled)
651 {
652
653 m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
654 UserProfilePick pick = new UserProfilePick();
655 string serverURI = string.Empty;
656 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
657 ScenePresence p = FindPresence(remoteClient.AgentId);
658
659 Vector3 avaPos = p.AbsolutePosition;
660 // Getting the global position for the Avatar
661 Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X,
662 remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y,
663 avaPos.Z);
664
665 string landOwnerName = string.Empty;
666 ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y);
667 if(land.LandData.IsGroupOwned)
668 {
669 IGroupsModule groupMod = p.Scene.RequestModuleInterface<IGroupsModule>();
670 UUID groupId = land.LandData.GroupID;
671 GroupRecord groupRecord = groupMod.GetGroupRecord(groupId);
672 landOwnerName = groupRecord.GroupName;
673 }
674 else
675 {
676 IUserAccountService accounts = p.Scene.RequestModuleInterface<IUserAccountService>();
677 UserAccount user = accounts.GetUserAccount(p.Scene.RegionInfo.ScopeID, land.LandData.OwnerID);
678 landOwnerName = user.Name;
679 }
680
681 pick.PickId = pickID;
682 pick.CreatorId = creatorID;
683 pick.TopPick = topPick;
684 pick.Name = name;
685 pick.Desc = desc;
686 pick.ParcelId = p.currentParcelUUID;
687 pick.SnapshotId = snapshotID;
688 pick.User = landOwnerName;
689 pick.SimName = remoteClient.Scene.RegionInfo.RegionName;
690 pick.GlobalPos = posGlobal.ToString();
691 pick.SortOrder = sortOrder;
692 pick.Enabled = enabled;
693
694 object Pick = (object)pick;
695 if(!JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString()))
696 {
697 remoteClient.SendAgentAlertMessage(
698 "Error updating pick", false);
699 }
700
701 m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString());
702 }
703
704 /// <summary>
705 /// Delete a Pick
706 /// </summary>
707 /// <param name='remoteClient'>
708 /// Remote client.
709 /// </param>
710 /// <param name='queryPickID'>
711 /// Query pick I.
712 /// </param>
713 public void PickDelete(IClientAPI remoteClient, UUID queryPickID)
714 {
715 string serverURI = string.Empty;
716 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
717
718 OSDMap parameters= new OSDMap();
719 parameters.Add("pickId", OSD.FromUUID(queryPickID));
720 OSD Params = (OSD)parameters;
721 if(!JsonRpcRequest(ref Params, "picks_delete", serverURI, UUID.Random().ToString()))
722 {
723 remoteClient.SendAgentAlertMessage(
724 "Error picks delete", false);
725 }
726 }
727 #endregion Picks
728
729 #region Notes
730 /// <summary>
731 /// Handles the avatar notes request.
732 /// </summary>
733 /// <param name='sender'>
734 /// Sender.
735 /// </param>
736 /// <param name='method'>
737 /// Method.
738 /// </param>
739 /// <param name='args'>
740 /// Arguments.
741 /// </param>
742 public void NotesRequest(Object sender, string method, List<String> args)
743 {
744 UserProfileNotes note = new UserProfileNotes();
745
746 if (!(sender is IClientAPI))
747 return;
748
749 IClientAPI remoteClient = (IClientAPI)sender;
750 string serverURI = string.Empty;
751 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
752 note.TargetId = remoteClient.AgentId;
753 UUID.TryParse(args[0], out note.UserId);
754
755 object Note = (object)note;
756 if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString()))
757 {
758 remoteClient.SendAgentAlertMessage(
759 "Error requesting note", false);
760 }
761 note = (UserProfileNotes) Note;
762
763 remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes);
764 }
765
766 /// <summary>
767 /// Avatars the notes update.
768 /// </summary>
769 /// <param name='remoteClient'>
770 /// Remote client.
771 /// </param>
772 /// <param name='queryTargetID'>
773 /// Query target I.
774 /// </param>
775 /// <param name='queryNotes'>
776 /// Query notes.
777 /// </param>
778 public void NotesUpdate(IClientAPI remoteClient, UUID queryTargetID, string queryNotes)
779 {
780 UserProfileNotes note = new UserProfileNotes();
781
782 note.UserId = remoteClient.AgentId;
783 note.TargetId = queryTargetID;
784 note.Notes = queryNotes;
785
786 string serverURI = string.Empty;
787 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
788
789 object Note = note;
790 if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString()))
791 {
792 remoteClient.SendAgentAlertMessage(
793 "Error updating note", false);
794 }
795 }
796 #endregion Notes
797
798 #region Avatar Properties
799 /// <summary>
800 /// Update the avatars interests .
801 /// </summary>
802 /// <param name='remoteClient'>
803 /// Remote client.
804 /// </param>
805 /// <param name='wantmask'>
806 /// Wantmask.
807 /// </param>
808 /// <param name='wanttext'>
809 /// Wanttext.
810 /// </param>
811 /// <param name='skillsmask'>
812 /// Skillsmask.
813 /// </param>
814 /// <param name='skillstext'>
815 /// Skillstext.
816 /// </param>
817 /// <param name='languages'>
818 /// Languages.
819 /// </param>
820 public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages)
821 {
822 UserProfileProperties prop = new UserProfileProperties();
823
824 prop.UserId = remoteClient.AgentId;
825 prop.WantToMask = (int)wantmask;
826 prop.WantToText = wanttext;
827 prop.SkillsMask = (int)skillsmask;
828 prop.SkillsText = skillstext;
829 prop.Language = languages;
830
831 string serverURI = string.Empty;
832 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
833
834 object Param = prop;
835 if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString()))
836 {
837 remoteClient.SendAgentAlertMessage(
838 "Error updating interests", false);
839 }
840 }
841
842 public void BasicRequestProperties(IClientAPI remoteClient, UUID avatarID)
843 {
844 IScene s = remoteClient.Scene;
845 if (!(s is Scene))
846 return;
847
848 string profileUrl = String.Empty;
849 string aboutText = String.Empty;
850 string firstLifeAboutText = String.Empty;
851 UUID image = UUID.Zero;
852 UUID firstLifeImage = UUID.Zero;
853 UUID partner = UUID.Zero;
854 uint wantMask = 0;
855 string wantText = String.Empty;
856 uint skillsMask = 0;
857 string skillsText = String.Empty;
858 string languages = String.Empty;
859
860 UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID);
861
862 string name = "Avatar";
863 int created = 0;
864 if (account != null)
865 {
866 name = account.FirstName + " " + account.LastName;
867 created = account.Created;
868 }
869 Byte[] charterMember = Utils.StringToBytes(name);
870
871 profileUrl = "No profile data";
872 aboutText = string.Empty;
873 firstLifeAboutText = string.Empty;
874 image = UUID.Zero;
875 firstLifeImage = UUID.Zero;
876 partner = UUID.Zero;
877
878 remoteClient.SendAvatarProperties(avatarID, aboutText,
879 Util.ToDateTime(created).ToString(
880 "M/d/yyyy", CultureInfo.InvariantCulture),
881 charterMember, firstLifeAboutText,
882 (uint)(0 & 0xff),
883 firstLifeImage, image, profileUrl, partner);
884
885 //Viewer expects interest data when it asks for properties.
886 remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
887 skillsMask, skillsText, languages);
888 }
889
890 /// <summary>
891 /// Requests the avatar properties.
892 /// </summary>
893 /// <param name='remoteClient'>
894 /// Remote client.
895 /// </param>
896 /// <param name='avatarID'>
897 /// Avatar I.
898 /// </param>
899 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
900 {
901 if ( String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString()))
902 {
903 // Looking for a reason that some viewers are sending null Id's
904 m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID);
905 return;
906 }
907
908 // Can't handle NPC yet...
909 ScenePresence p = FindPresence(avatarID);
910
911 if (null != p)
912 {
913 if (p.PresenceType == PresenceType.Npc)
914 return;
915 }
916
917 string serverURI = string.Empty;
918 bool foreign = GetUserProfileServerURI(avatarID, out serverURI);
919
920 UserAccount account = null;
921 Dictionary<string,object> userInfo;
922
923 if (!foreign)
924 {
925 account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID);
926 }
927 else
928 {
929 userInfo = new Dictionary<string, object>();
930 }
931
932 Byte[] charterMember = new Byte[1];
933 string born = String.Empty;
934 uint flags = 0x00;
935
936 if (null != account)
937 {
938 if (account.UserTitle == "")
939 {
940 charterMember[0] = (Byte)((account.UserFlags & 0xf00) >> 8);
941 }
942 else
943 {
944 charterMember = Utils.StringToBytes(account.UserTitle);
945 }
946
947 born = Util.ToDateTime(account.Created).ToString(
948 "M/d/yyyy", CultureInfo.InvariantCulture);
949 flags = (uint)(account.UserFlags & 0xff);
950 }
951 else
952 {
953 if (GetUserAccountData(avatarID, out userInfo) == true)
954 {
955 if ((string)userInfo["user_title"] == "")
956 {
957 charterMember[0] = (Byte)(((Byte)userInfo["user_flags"] & 0xf00) >> 8);
958 }
959 else
960 {
961 charterMember = Utils.StringToBytes((string)userInfo["user_title"]);
962 }
963
964 int val_born = (int)userInfo["user_created"];
965 born = Util.ToDateTime(val_born).ToString(
966 "M/d/yyyy", CultureInfo.InvariantCulture);
967
968 // picky, picky
969 int val_flags = (int)userInfo["user_flags"];
970 flags = (uint)(val_flags & 0xff);
971 }
972 }
973
974 UserProfileProperties props = new UserProfileProperties();
975 string result = string.Empty;
976
977 props.UserId = avatarID;
978 GetProfileData(ref props, out result);
979
980 remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags,
981 props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
982
983
984 remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask,
985 props.SkillsText, props.Language);
986 }
987
988 /// <summary>
989 /// Updates the avatar properties.
990 /// </summary>
991 /// <param name='remoteClient'>
992 /// Remote client.
993 /// </param>
994 /// <param name='newProfile'>
995 /// New profile.
996 /// </param>
997 public void AvatarPropertiesUpdate(IClientAPI remoteClient, UserProfileData newProfile)
998 {
999 if (remoteClient.AgentId == newProfile.ID)
1000 {
1001 UserProfileProperties prop = new UserProfileProperties();
1002
1003 prop.UserId = remoteClient.AgentId;
1004 prop.WebUrl = newProfile.ProfileUrl;
1005 prop.ImageId = newProfile.Image;
1006 prop.AboutText = newProfile.AboutText;
1007 prop.FirstLifeImageId = newProfile.FirstLifeImage;
1008 prop.FirstLifeText = newProfile.FirstLifeAboutText;
1009
1010 string serverURI = string.Empty;
1011 bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
1012
1013 object Prop = prop;
1014
1015 if(!JsonRpcRequest(ref Prop, "avatar_properties_update", serverURI, UUID.Random().ToString()))
1016 {
1017 remoteClient.SendAgentAlertMessage(
1018 "Error updating properties", false);
1019 }
1020
1021 RequestAvatarProperties(remoteClient, newProfile.ID);
1022 }
1023 }
1024
1025
1026 /// <summary>
1027 /// Gets the profile data.
1028 /// </summary>
1029 /// <returns>
1030 /// The profile data.
1031 /// </returns>
1032 /// <param name='userID'>
1033 /// User I.
1034 /// </param>
1035 bool GetProfileData(ref UserProfileProperties properties, out string message)
1036 {
1037 // Can't handle NPC yet...
1038 ScenePresence p = FindPresence(properties.UserId);
1039
1040 if (null != p)
1041 {
1042 if (p.PresenceType == PresenceType.Npc)
1043 {
1044 message = "Id points to NPC";
1045 return false;
1046 }
1047 }
1048
1049 string serverURI = string.Empty;
1050 bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI);
1051
1052 // This is checking a friend on the home grid
1053 // Not HG friend
1054 if ( String.IsNullOrEmpty(serverURI))
1055 {
1056 message = "No Presence - foreign friend";
1057 return false;
1058 }
1059
1060 object Prop = (object)properties;
1061 JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString());
1062 properties = (UserProfileProperties)Prop;
1063
1064 message = "Success";
1065 return true;
1066 }
1067 #endregion Avatar Properties
1068
1069 #region Utils
1070 bool GetImageAssets(UUID avatarId)
1071 {
1072 string profileServerURI = string.Empty;
1073 string assetServerURI = string.Empty;
1074
1075 bool foreign = GetUserProfileServerURI(avatarId, out profileServerURI);
1076
1077 if(!foreign)
1078 return true;
1079
1080 assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI");
1081
1082 OSDMap parameters= new OSDMap();
1083 parameters.Add("avatarId", OSD.FromUUID(avatarId));
1084 OSD Params = (OSD)parameters;
1085 if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString()))
1086 {
1087 // Error Handling here!
1088 // if(parameters.ContainsKey("message")
1089 return false;
1090 }
1091
1092 parameters = (OSDMap)Params;
1093
1094 OSDArray list = (OSDArray)parameters["result"];
1095
1096 foreach(OSD asset in list)
1097 {
1098 OSDString assetId = (OSDString)asset;
1099
1100 Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString()), this,
1101 delegate (string assetID, Object s, AssetBase a)
1102 {
1103 // m_log.DebugFormat("[PROFILES]: Getting Image Assets {0}", assetID);
1104 return;
1105 });
1106 }
1107 return true;
1108 }
1109
1110 /// <summary>
1111 /// Gets the user account data.
1112 /// </summary>
1113 /// <returns>
1114 /// The user profile data.
1115 /// </returns>
1116 /// <param name='userID'>
1117 /// If set to <c>true</c> user I.
1118 /// </param>
1119 /// <param name='userInfo'>
1120 /// If set to <c>true</c> user info.
1121 /// </param>
1122 bool GetUserAccountData(UUID userID, out Dictionary<string, object> userInfo)
1123 {
1124 Dictionary<string,object> info = new Dictionary<string, object>();
1125
1126 if (UserManagementModule.IsLocalGridUser(userID))
1127 {
1128 // Is local
1129 IUserAccountService uas = Scene.UserAccountService;
1130 UserAccount account = uas.GetUserAccount(Scene.RegionInfo.ScopeID, userID);
1131
1132 info["user_flags"] = account.UserFlags;
1133 info["user_created"] = account.Created;
1134
1135 if (!String.IsNullOrEmpty(account.UserTitle))
1136 info["user_title"] = account.UserTitle;
1137 else
1138 info["user_title"] = "";
1139
1140 userInfo = info;
1141
1142 return false;
1143 }
1144 else
1145 {
1146 // Is Foreign
1147 string home_url = UserManagementModule.GetUserServerURL(userID, "HomeURI");
1148
1149 if (String.IsNullOrEmpty(home_url))
1150 {
1151 info["user_flags"] = 0;
1152 info["user_created"] = 0;
1153 info["user_title"] = "Unavailable";
1154
1155 userInfo = info;
1156 return true;
1157 }
1158
1159 UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url);
1160
1161 Dictionary<string, object> account = uConn.GetUserInfo(userID);
1162
1163 if (account.Count > 0)
1164 {
1165 if (account.ContainsKey("user_flags"))
1166 info["user_flags"] = account["user_flags"];
1167 else
1168 info["user_flags"] = "";
1169
1170 if (account.ContainsKey("user_created"))
1171 info["user_created"] = account["user_created"];
1172 else
1173 info["user_created"] = "";
1174
1175 info["user_title"] = "HG Visitor";
1176 }
1177 else
1178 {
1179 info["user_flags"] = 0;
1180 info["user_created"] = 0;
1181 info["user_title"] = "HG Visitor";
1182 }
1183 userInfo = info;
1184 return true;
1185 }
1186 }
1187
1188 /// <summary>
1189 /// Gets the user profile server UR.
1190 /// </summary>
1191 /// <returns>
1192 /// The user profile server UR.
1193 /// </returns>
1194 /// <param name='userID'>
1195 /// If set to <c>true</c> user I.
1196 /// </param>
1197 /// <param name='serverURI'>
1198 /// If set to <c>true</c> server UR.
1199 /// </param>
1200 bool GetUserProfileServerURI(UUID userID, out string serverURI)
1201 {
1202 bool local;
1203 local = UserManagementModule.IsLocalGridUser(userID);
1204
1205 if (!local)
1206 {
1207 serverURI = UserManagementModule.GetUserServerURL(userID, "ProfileServerURI");
1208 // Is Foreign
1209 return true;
1210 }
1211 else
1212 {
1213 serverURI = ProfileServerUri;
1214 // Is local
1215 return false;
1216 }
1217 }
1218
1219 /// <summary>
1220 /// Finds the presence.
1221 /// </summary>
1222 /// <returns>
1223 /// The presence.
1224 /// </returns>
1225 /// <param name='clientID'>
1226 /// Client I.
1227 /// </param>
1228 ScenePresence FindPresence(UUID clientID)
1229 {
1230 ScenePresence p;
1231
1232 p = Scene.GetScenePresence(clientID);
1233 if (p != null && !p.IsChildAgent)
1234 return p;
1235
1236 return null;
1237 }
1238 #endregion Util
1239
1240 #region Web Util
1241 /// <summary>
1242 /// Sends json-rpc request with a serializable type.
1243 /// </summary>
1244 /// <returns>
1245 /// OSD Map.
1246 /// </returns>
1247 /// <param name='parameters'>
1248 /// Serializable type .
1249 /// </param>
1250 /// <param name='method'>
1251 /// Json-rpc method to call.
1252 /// </param>
1253 /// <param name='uri'>
1254 /// URI of json-rpc service.
1255 /// </param>
1256 /// <param name='jsonId'>
1257 /// Id for our call.
1258 /// </param>
1259 bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId)
1260 {
1261 if (jsonId == null)
1262 throw new ArgumentNullException ("jsonId");
1263 if (uri == null)
1264 throw new ArgumentNullException ("uri");
1265 if (method == null)
1266 throw new ArgumentNullException ("method");
1267 if (parameters == null)
1268 throw new ArgumentNullException ("parameters");
1269
1270 // Prep our payload
1271 OSDMap json = new OSDMap();
1272
1273 json.Add("jsonrpc", OSD.FromString("2.0"));
1274 json.Add("id", OSD.FromString(jsonId));
1275 json.Add("method", OSD.FromString(method));
1276 // Experiment
1277 json.Add("params", OSD.SerializeMembers(parameters));
1278
1279 string jsonRequestData = OSDParser.SerializeJsonString(json);
1280 byte[] content = Encoding.UTF8.GetBytes(jsonRequestData);
1281
1282 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
1283 // webRequest.Credentials = new NetworkCredential(rpcUser, rpcPass);
1284 webRequest.ContentType = "application/json-rpc";
1285 webRequest.Method = "POST";
1286
1287 Stream dataStream = webRequest.GetRequestStream();
1288 dataStream.Write(content, 0, content.Length);
1289 dataStream.Close();
1290
1291 WebResponse webResponse = null;
1292 try
1293 {
1294 webResponse = webRequest.GetResponse();
1295 }
1296 catch (WebException e)
1297 {
1298 Console.WriteLine("Web Error" + e.Message);
1299 Console.WriteLine ("Please check input");
1300 return false;
1301 }
1302
1303 byte[] buf = new byte[8192];
1304 Stream rstream = webResponse.GetResponseStream();
1305 OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream);
1306
1307 if(mret.ContainsKey("error"))
1308 return false;
1309
1310 // get params...
1311 OSD.DeserializeMembers(ref parameters, (OSDMap) mret["result"]);
1312 return true;
1313 }
1314
1315 /// <summary>
1316 /// Sends json-rpc request with OSD parameter.
1317 /// </summary>
1318 /// <returns>
1319 /// The rpc request.
1320 /// </returns>
1321 /// <param name='data'>
1322 /// data - incoming as parameters, outgong as result/error
1323 /// </param>
1324 /// <param name='method'>
1325 /// Json-rpc method to call.
1326 /// </param>
1327 /// <param name='uri'>
1328 /// URI of json-rpc service.
1329 /// </param>
1330 /// <param name='jsonId'>
1331 /// If set to <c>true</c> json identifier.
1332 /// </param>
1333 bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId)
1334 {
1335 OSDMap map = new OSDMap();
1336
1337 map["jsonrpc"] = "2.0";
1338 if(string.IsNullOrEmpty(jsonId))
1339 map["id"] = UUID.Random().ToString();
1340 else
1341 map["id"] = jsonId;
1342
1343 map["method"] = method;
1344 map["params"] = data;
1345
1346 string jsonRequestData = OSDParser.SerializeJsonString(map);
1347 byte[] content = Encoding.UTF8.GetBytes(jsonRequestData);
1348
1349 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
1350 webRequest.ContentType = "application/json-rpc";
1351 webRequest.Method = "POST";
1352
1353 Stream dataStream = webRequest.GetRequestStream();
1354 dataStream.Write(content, 0, content.Length);
1355 dataStream.Close();
1356
1357 WebResponse webResponse = null;
1358 try
1359 {
1360 webResponse = webRequest.GetResponse();
1361 }
1362 catch (WebException e)
1363 {
1364 Console.WriteLine("Web Error" + e.Message);
1365 Console.WriteLine ("Please check input");
1366 return false;
1367 }
1368
1369 byte[] buf = new byte[8192];
1370 Stream rstream = webResponse.GetResponseStream();
1371
1372 OSDMap response = new OSDMap();
1373 response = (OSDMap)OSDParser.DeserializeJson(rstream);
1374 if(response.ContainsKey("error"))
1375 {
1376 data = response["error"];
1377 return false;
1378 }
1379
1380 data = response;
1381
1382 return true;
1383 }
1384 #endregion Web Util
1385 }
1386}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs
new file mode 100644
index 0000000..323535a
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs
@@ -0,0 +1,226 @@
1
2/*
3 * Copyright (c) Contributors, http://opensimulator.org/
4 * See CONTRIBUTORS.TXT for a full list of copyright holders.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the OpenSimulator Project nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29using log4net;
30using Mono.Addins;
31using Nini.Config;
32using System;
33using System.Collections.Generic;
34using System.Reflection;
35using OpenSim.Framework;
36using OpenSim.Framework.Console;
37using OpenSim.Server.Base;
38using OpenSim.Server.Handlers;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Framework.Servers;
42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Services.Interfaces;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45using OpenMetaverse;
46
47namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile
48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalUserProfilesServicesConnector")]
50 public class LocalUserProfilesServicesConnector : ISharedRegionModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Dictionary<UUID, Scene> regions = new Dictionary<UUID, Scene>();
57
58 public IUserProfilesService ServiceModule
59 {
60 get; private set;
61 }
62
63 public bool Enabled
64 {
65 get; private set;
66 }
67
68 public string Name
69 {
70 get
71 {
72 return "LocalUserProfilesServicesConnector";
73 }
74 }
75
76 public string ConfigName
77 {
78 get; private set;
79 }
80
81 public Type ReplaceableInterface
82 {
83 get { return null; }
84 }
85
86 public LocalUserProfilesServicesConnector()
87 {
88 m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector no params");
89 }
90
91 public LocalUserProfilesServicesConnector(IConfigSource source)
92 {
93 m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector instantiated directly.");
94 InitialiseService(source);
95 }
96
97 public void InitialiseService(IConfigSource source)
98 {
99 ConfigName = "UserProfilesService";
100
101 // Instantiate the request handler
102 IHttpServer Server = MainServer.Instance;
103
104 IConfig config = source.Configs[ConfigName];
105 if (config == null)
106 {
107 m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: UserProfilesService missing from OpenSim.ini");
108 return;
109 }
110
111 if(!config.GetBoolean("Enabled",false))
112 {
113 Enabled = false;
114 return;
115 }
116
117 Enabled = true;
118
119 string serviceDll = config.GetString("LocalServiceModule",
120 String.Empty);
121
122 if (serviceDll == String.Empty)
123 {
124 m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: No LocalServiceModule named in section UserProfilesService");
125 return;
126 }
127
128 Object[] args = new Object[] { source, ConfigName };
129 ServiceModule =
130 ServerUtils.LoadPlugin<IUserProfilesService>(serviceDll,
131 args);
132
133 if (ServiceModule == null)
134 {
135 m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: Can't load user profiles service");
136 return;
137 }
138
139 Enabled = true;
140
141 JsonRpcProfileHandlers handler = new JsonRpcProfileHandlers(ServiceModule);
142
143 Server.AddJsonRPCHandler("avatarclassifiedsrequest", handler.AvatarClassifiedsRequest);
144 Server.AddJsonRPCHandler("classified_update", handler.ClassifiedUpdate);
145 Server.AddJsonRPCHandler("classifieds_info_query", handler.ClassifiedInfoRequest);
146 Server.AddJsonRPCHandler("classified_delete", handler.ClassifiedDelete);
147 Server.AddJsonRPCHandler("avatarpicksrequest", handler.AvatarPicksRequest);
148 Server.AddJsonRPCHandler("pickinforequest", handler.PickInfoRequest);
149 Server.AddJsonRPCHandler("picks_update", handler.PicksUpdate);
150 Server.AddJsonRPCHandler("picks_delete", handler.PicksDelete);
151 Server.AddJsonRPCHandler("avatarnotesrequest", handler.AvatarNotesRequest);
152 Server.AddJsonRPCHandler("avatar_notes_update", handler.NotesUpdate);
153 Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
154 Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
155 Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
156 Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
157 Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
158 Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);
159
160 }
161
162 #region ISharedRegionModule implementation
163
164 void ISharedRegionModule.PostInitialise()
165 {
166 if(!Enabled)
167 return;
168 }
169
170 #endregion
171
172 #region IRegionModuleBase implementation
173
174 void IRegionModuleBase.Initialise(IConfigSource source)
175 {
176 IConfig moduleConfig = source.Configs["Modules"];
177 if (moduleConfig != null)
178 {
179 string name = moduleConfig.GetString("UserProfilesServices", "");
180 if (name == Name)
181 {
182 InitialiseService(source);
183 m_log.Info("[LOCAL USERPROFILES SERVICE CONNECTOR]: Local user profiles connector enabled");
184 }
185 }
186 }
187
188 void IRegionModuleBase.Close()
189 {
190 return;
191 }
192
193 void IRegionModuleBase.AddRegion(Scene scene)
194 {
195 if (!Enabled)
196 return;
197
198 lock (regions)
199 {
200 if (regions.ContainsKey(scene.RegionInfo.RegionID))
201 m_log.ErrorFormat("[LOCAL USERPROFILES SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
202 else
203 regions.Add(scene.RegionInfo.RegionID, scene);
204 }
205 }
206
207 void IRegionModuleBase.RemoveRegion(Scene scene)
208 {
209 if (!Enabled)
210 return;
211
212 lock (regions)
213 {
214 if (regions.ContainsKey(scene.RegionInfo.RegionID))
215 regions.Remove(scene.RegionInfo.RegionID);
216 }
217 }
218
219 void IRegionModuleBase.RegionLoaded(Scene scene)
220 {
221 if (!Enabled)
222 return;
223 }
224 #endregion
225 }
226} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index c32820e..3849a3f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
56 56
57 public LocalGridServicesConnector() 57 public LocalGridServicesConnector()
58 { 58 {
59 m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector no parms.");
59 } 60 }
60 61
61 public LocalGridServicesConnector(IConfigSource source) 62 public LocalGridServicesConnector(IConfigSource source)
diff --git a/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs b/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs
new file mode 100644
index 0000000..4ad7297
--- /dev/null
+++ b/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs
@@ -0,0 +1,92 @@
1using System;
2using System.Reflection;
3using Nini.Config;
4using OpenSim.Server.Base;
5using OpenSim.Services.Interfaces;
6using OpenSim.Framework.Servers.HttpServer;
7using OpenSim.Framework;
8using OpenSim.Server.Handlers.Base;
9using log4net;
10
11namespace OpenSim.Server.Handlers.Profiles
12{
13 public class UserProfilesConnector: ServiceConnector
14 {
15 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
16
17
18 // Our Local Module
19 public IUserProfilesService ServiceModule
20 {
21 get; private set;
22 }
23
24 // The HTTP server.
25 public IHttpServer Server
26 {
27 get; private set;
28 }
29
30 public string ConfigName
31 {
32 get; private set;
33 }
34
35 public bool Enabled
36 {
37 get; private set;
38 }
39
40 public UserProfilesConnector(IConfigSource config, IHttpServer server, string configName) :
41 base(config, server, configName)
42 {
43 ConfigName = "UserProfilesService";
44 if(!string.IsNullOrEmpty(configName))
45 ConfigName = configName;
46
47 IConfig serverConfig = config.Configs[ConfigName];
48 if (serverConfig == null)
49 throw new Exception(String.Format("No section {0} in config file", ConfigName));
50
51 if(!serverConfig.GetBoolean("Enabled",false))
52 {
53 Enabled = false;
54 return;
55 }
56
57 Enabled = true;
58
59 Server = server;
60
61 string service = serverConfig.GetString("LocalServiceModule", String.Empty);
62
63 Object[] args = new Object[] { config, ConfigName };
64 ServiceModule = ServerUtils.LoadPlugin<IUserProfilesService>(service, args);
65
66 JsonRpcProfileHandlers handler = new JsonRpcProfileHandlers(ServiceModule);
67
68 Server.AddJsonRPCHandler("avatarclassifiedsrequest", handler.AvatarClassifiedsRequest);
69 Server.AddJsonRPCHandler("classified_update", handler.ClassifiedUpdate);
70 Server.AddJsonRPCHandler("classifieds_info_query", handler.ClassifiedInfoRequest);
71 Server.AddJsonRPCHandler("classified_delete", handler.ClassifiedDelete);
72 Server.AddJsonRPCHandler("avatarpicksrequest", handler.AvatarPicksRequest);
73 Server.AddJsonRPCHandler("pickinforequest", handler.PickInfoRequest);
74 Server.AddJsonRPCHandler("picks_update", handler.PicksUpdate);
75 Server.AddJsonRPCHandler("picks_delete", handler.PicksDelete);
76 Server.AddJsonRPCHandler("avatarnotesrequest", handler.AvatarNotesRequest);
77 Server.AddJsonRPCHandler("avatar_notes_update", handler.NotesUpdate);
78 Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
79 Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
80 Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
81 Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
82// Server.AddJsonRPCHandler("user_preferences_request", handler.UserPreferencesRequest);
83// Server.AddJsonRPCHandler("user_preferences_update", handler.UserPreferencesUpdate);
84// Server.AddJsonRPCHandler("user_account_create", handler.UserAccountCreate);
85// Server.AddJsonRPCHandler("user_account_auth", handler.UserAccountAuth);
86// Server.AddJsonRPCHandler("user_account_test", handler.UserAccountTest);
87 Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
88 Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);
89 }
90 }
91}
92
diff --git a/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs b/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs
new file mode 100644
index 0000000..93da102
--- /dev/null
+++ b/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs
@@ -0,0 +1,434 @@
1using System;
2using System.Reflection;
3using OpenMetaverse;
4using OpenMetaverse.StructuredData;
5using log4net;
6using OpenSim.Services.Interfaces;
7using OpenSim.Framework.Servers.HttpServer;
8using OpenSim.Framework;
9
10namespace OpenSim.Server.Handlers
11{
12 public class UserProfilesHandlers
13 {
14 public UserProfilesHandlers ()
15 {
16 }
17 }
18
19 public class JsonRpcProfileHandlers
20 {
21 static readonly ILog m_log =
22 LogManager.GetLogger(
23 MethodBase.GetCurrentMethod().DeclaringType);
24
25 public IUserProfilesService Service
26 {
27 get; private set;
28 }
29
30 public JsonRpcProfileHandlers(IUserProfilesService service)
31 {
32 Service = service;
33 }
34
35 #region Classifieds
36 /// <summary>
37 /// Request avatar's classified ads.
38 /// </summary>
39 /// <returns>
40 /// An array containing all the calassified uuid and it's name created by the creator id
41 /// </returns>
42 /// <param name='json'>
43 /// Our parameters are in the OSDMap json["params"]
44 /// </param>
45 /// <param name='response'>
46 /// If set to <c>true</c> response.
47 /// </param>
48 public bool AvatarClassifiedsRequest(OSDMap json, ref JsonRpcResponse response)
49 {
50 if(!json.ContainsKey("params"))
51 {
52 response.Error.Code = ErrorCode.ParseError;
53 m_log.DebugFormat ("Classified Request");
54 return false;
55 }
56
57 OSDMap request = (OSDMap)json["params"];
58 UUID creatorId = new UUID(request["creatorId"].AsString());
59
60
61 OSDArray data = (OSDArray) Service.AvatarClassifiedsRequest(creatorId);
62 response.Result = data;
63
64 return true;
65 }
66
67 public bool ClassifiedUpdate(OSDMap json, ref JsonRpcResponse response)
68 {
69 if(!json.ContainsKey("params"))
70 {
71 response.Error.Code = ErrorCode.ParseError;
72 response.Error.Message = "Error parsing classified update request";
73 m_log.DebugFormat ("Classified Update Request");
74 return false;
75 }
76
77 string result = string.Empty;
78 UserClassifiedAdd ad = new UserClassifiedAdd();
79 object Ad = (object)ad;
80 OSD.DeserializeMembers(ref Ad, (OSDMap)json["params"]);
81 if(Service.ClassifiedUpdate(ad, ref result))
82 {
83 response.Result = OSD.SerializeMembers(ad);
84 return true;
85 }
86
87 response.Error.Code = ErrorCode.InternalError;
88 response.Error.Message = string.Format("{0}", result);
89 return false;
90 }
91
92 public bool ClassifiedDelete(OSDMap json, ref JsonRpcResponse response)
93 {
94 if(!json.ContainsKey("params"))
95 {
96 response.Error.Code = ErrorCode.ParseError;
97 m_log.DebugFormat ("Classified Delete Request");
98 return false;
99 }
100
101 OSDMap request = (OSDMap)json["params"];
102 UUID classifiedId = new UUID(request["classifiedID"].AsString());
103
104 OSDMap res = new OSDMap();
105 res["result"] = OSD.FromString("success");
106 response.Result = res;
107
108 return true;
109
110 }
111
112 public bool ClassifiedInfoRequest(OSDMap json, ref JsonRpcResponse response)
113 {
114 if(!json.ContainsKey("params"))
115 {
116 response.Error.Code = ErrorCode.ParseError;
117 response.Error.Message = "no parameters supplied";
118 m_log.DebugFormat ("Classified Info Request");
119 return false;
120 }
121
122 string result = string.Empty;
123 UserClassifiedAdd ad = new UserClassifiedAdd();
124 object Ad = (object)ad;
125 OSD.DeserializeMembers(ref Ad, (OSDMap)json["params"]);
126 if(Service.ClassifiedInfoRequest(ref ad, ref result))
127 {
128 response.Result = OSD.SerializeMembers(ad);
129 return true;
130 }
131
132 response.Error.Code = ErrorCode.InternalError;
133 response.Error.Message = string.Format("{0}", result);
134 return false;
135 }
136 #endregion Classifieds
137
138 #region Picks
139 public bool AvatarPicksRequest(OSDMap json, ref JsonRpcResponse response)
140 {
141 if(!json.ContainsKey("params"))
142 {
143 response.Error.Code = ErrorCode.ParseError;
144 m_log.DebugFormat ("Avatar Picks Request");
145 return false;
146 }
147
148 OSDMap request = (OSDMap)json["params"];
149 UUID creatorId = new UUID(request["creatorId"].AsString());
150
151
152 OSDArray data = (OSDArray) Service.AvatarPicksRequest(creatorId);
153 response.Result = data;
154
155 return true;
156 }
157
158 public bool PickInfoRequest(OSDMap json, ref JsonRpcResponse response)
159 {
160 if(!json.ContainsKey("params"))
161 {
162 response.Error.Code = ErrorCode.ParseError;
163 response.Error.Message = "no parameters supplied";
164 m_log.DebugFormat ("Avatar Picks Info Request");
165 return false;
166 }
167
168 string result = string.Empty;
169 UserProfilePick pick = new UserProfilePick();
170 object Pick = (object)pick;
171 OSD.DeserializeMembers(ref Pick, (OSDMap)json["params"]);
172 if(Service.PickInfoRequest(ref pick, ref result))
173 {
174 response.Result = OSD.SerializeMembers(pick);
175 return true;
176 }
177
178 response.Error.Code = ErrorCode.InternalError;
179 response.Error.Message = string.Format("{0}", result);
180 return false;
181 }
182
183 public bool PicksUpdate(OSDMap json, ref JsonRpcResponse response)
184 {
185 if(!json.ContainsKey("params"))
186 {
187 response.Error.Code = ErrorCode.ParseError;
188 response.Error.Message = "no parameters supplied";
189 m_log.DebugFormat ("Avatar Picks Update Request");
190 return false;
191 }
192
193 string result = string.Empty;
194 UserProfilePick pick = new UserProfilePick();
195 object Pick = (object)pick;
196 OSD.DeserializeMembers(ref Pick, (OSDMap)json["params"]);
197 if(Service.PicksUpdate(ref pick, ref result))
198 {
199 response.Result = OSD.SerializeMembers(pick);
200 return true;
201 }
202
203 response.Error.Code = ErrorCode.InternalError;
204 response.Error.Message = "unable to update pick";
205
206 return false;
207 }
208
209 public bool PicksDelete(OSDMap json, ref JsonRpcResponse response)
210 {
211 if(!json.ContainsKey("params"))
212 {
213 response.Error.Code = ErrorCode.ParseError;
214 m_log.DebugFormat ("Avatar Picks Delete Request");
215 return false;
216 }
217
218 OSDMap request = (OSDMap)json["params"];
219 UUID pickId = new UUID(request["pickId"].AsString());
220 if(Service.PicksDelete(pickId))
221 return true;
222
223 response.Error.Code = ErrorCode.InternalError;
224 response.Error.Message = "data error removing record";
225 return false;
226 }
227 #endregion Picks
228
229 #region Notes
230 public bool AvatarNotesRequest(OSDMap json, ref JsonRpcResponse response)
231 {
232 if(!json.ContainsKey("params"))
233 {
234 response.Error.Code = ErrorCode.ParseError;
235 response.Error.Message = "Params missing";
236 m_log.DebugFormat ("Avatar Notes Request");
237 return false;
238 }
239
240 string result = string.Empty;
241 UserProfileNotes note = new UserProfileNotes();
242 object Note = (object)note;
243 OSD.DeserializeMembers(ref Note, (OSDMap)json["params"]);
244 if(Service.AvatarNotesRequest(ref note))
245 {
246 response.Result = OSD.SerializeMembers(note);
247 return true;
248 }
249
250 object Notes = (object) note;
251 OSD.DeserializeMembers(ref Notes, (OSDMap)json["params"]);
252 return true;
253 }
254
255 public bool NotesUpdate(OSDMap json, ref JsonRpcResponse response)
256 {
257 if(!json.ContainsKey("params"))
258 {
259 response.Error.Code = ErrorCode.ParseError;
260 response.Error.Message = "No parameters";
261 m_log.DebugFormat ("Avatar Notes Update Request");
262 return false;
263 }
264
265 string result = string.Empty;
266 UserProfileNotes note = new UserProfileNotes();
267 object Notes = (object) note;
268 OSD.DeserializeMembers(ref Notes, (OSDMap)json["params"]);
269 if(Service.NotesUpdate(ref note, ref result))
270 {
271 response.Result = OSD.SerializeMembers(note);
272 return true;
273 }
274 return true;
275 }
276 #endregion Notes
277
278 #region Profile Properties
279 public bool AvatarPropertiesRequest(OSDMap json, ref JsonRpcResponse response)
280 {
281 if(!json.ContainsKey("params"))
282 {
283 response.Error.Code = ErrorCode.ParseError;
284 response.Error.Message = "no parameters supplied";
285 m_log.DebugFormat ("Avatar Properties Request");
286 return false;
287 }
288
289 string result = string.Empty;
290 UserProfileProperties props = new UserProfileProperties();
291 object Props = (object)props;
292 OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
293 if(Service.AvatarPropertiesRequest(ref props, ref result))
294 {
295 response.Result = OSD.SerializeMembers(props);
296 return true;
297 }
298
299 response.Error.Code = ErrorCode.InternalError;
300 response.Error.Message = string.Format("{0}", result);
301 return false;
302 }
303
304 public bool AvatarPropertiesUpdate(OSDMap json, ref JsonRpcResponse response)
305 {
306 if(!json.ContainsKey("params"))
307 {
308 response.Error.Code = ErrorCode.ParseError;
309 response.Error.Message = "no parameters supplied";
310 m_log.DebugFormat ("Avatar Properties Update Request");
311 return false;
312 }
313
314 string result = string.Empty;
315 UserProfileProperties props = new UserProfileProperties();
316 object Props = (object)props;
317 OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
318 if(Service.AvatarPropertiesUpdate(ref props, ref result))
319 {
320 response.Result = OSD.SerializeMembers(props);
321 return true;
322 }
323
324 response.Error.Code = ErrorCode.InternalError;
325 response.Error.Message = string.Format("{0}", result);
326 return false;
327 }
328 #endregion Profile Properties
329
330 #region Interests
331 public bool AvatarInterestsUpdate(OSDMap json, ref JsonRpcResponse response)
332 {
333 if(!json.ContainsKey("params"))
334 {
335 response.Error.Code = ErrorCode.ParseError;
336 response.Error.Message = "no parameters supplied";
337 m_log.DebugFormat ("Avatar Interests Update Request");
338 return false;
339 }
340
341 string result = string.Empty;
342 UserProfileProperties props = new UserProfileProperties();
343 object Props = (object)props;
344 OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
345 if(Service.AvatarInterestsUpdate(props, ref result))
346 {
347 response.Result = OSD.SerializeMembers(props);
348 return true;
349 }
350
351 response.Error.Code = ErrorCode.InternalError;
352 response.Error.Message = string.Format("{0}", result);
353 return false;
354 }
355 #endregion Interests
356
357 #region Utility
358 public bool AvatarImageAssetsRequest(OSDMap json, ref JsonRpcResponse response)
359 {
360 if(!json.ContainsKey("params"))
361 {
362 response.Error.Code = ErrorCode.ParseError;
363 m_log.DebugFormat ("Avatar Image Assets Request");
364 return false;
365 }
366
367 OSDMap request = (OSDMap)json["params"];
368 UUID avatarId = new UUID(request["avatarId"].AsString());
369
370 OSDArray data = (OSDArray) Service.AvatarImageAssetsRequest(avatarId);
371 response.Result = data;
372
373 return true;
374 }
375 #endregion Utiltiy
376
377 #region UserData
378 public bool RequestUserAppData(OSDMap json, ref JsonRpcResponse response)
379 {
380 if(!json.ContainsKey("params"))
381 {
382 response.Error.Code = ErrorCode.ParseError;
383 response.Error.Message = "no parameters supplied";
384 m_log.DebugFormat ("User Application Service URL Request: No Parameters!");
385 return false;
386 }
387
388 string result = string.Empty;
389 UserAppData props = new UserAppData();
390 object Props = (object)props;
391 OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
392 if(Service.RequestUserAppData(ref props, ref result))
393 {
394 OSDMap res = new OSDMap();
395 res["result"] = OSD.FromString("success");
396 res["token"] = OSD.FromString (result);
397 response.Result = res;
398
399 return true;
400 }
401
402 response.Error.Code = ErrorCode.InternalError;
403 response.Error.Message = string.Format("{0}", result);
404 return false;
405 }
406
407 public bool UpdateUserAppData(OSDMap json, ref JsonRpcResponse response)
408 {
409 if(!json.ContainsKey("params"))
410 {
411 response.Error.Code = ErrorCode.ParseError;
412 response.Error.Message = "no parameters supplied";
413 m_log.DebugFormat ("User App Data Update Request");
414 return false;
415 }
416
417 string result = string.Empty;
418 UserAppData props = new UserAppData();
419 object Props = (object)props;
420 OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
421 if(Service.SetUserAppData(props, ref result))
422 {
423 response.Result = OSD.SerializeMembers(props);
424 return true;
425 }
426
427 response.Error.Code = ErrorCode.InternalError;
428 response.Error.Message = string.Format("{0}", result);
429 return false;
430 }
431 #endregion UserData
432 }
433}
434
diff --git a/OpenSim/Services/Interfaces/IUserProfilesService.cs b/OpenSim/Services/Interfaces/IUserProfilesService.cs
new file mode 100644
index 0000000..12fc986
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IUserProfilesService.cs
@@ -0,0 +1,48 @@
1using System;
2using OpenSim.Framework;
3using OpenMetaverse;
4using OpenMetaverse.StructuredData;
5
6namespace OpenSim.Services.Interfaces
7{
8 public interface IUserProfilesService
9 {
10 #region Classifieds
11 OSD AvatarClassifiedsRequest(UUID creatorId);
12 bool ClassifiedUpdate(UserClassifiedAdd ad, ref string result);
13 bool ClassifiedInfoRequest(ref UserClassifiedAdd ad, ref string result);
14 bool ClassifiedDelete(UUID recordId);
15 #endregion Classifieds
16
17 #region Picks
18 OSD AvatarPicksRequest(UUID creatorId);
19 bool PickInfoRequest(ref UserProfilePick pick, ref string result);
20 bool PicksUpdate(ref UserProfilePick pick, ref string result);
21 bool PicksDelete(UUID pickId);
22 #endregion Picks
23
24 #region Notes
25 bool AvatarNotesRequest(ref UserProfileNotes note);
26 bool NotesUpdate(ref UserProfileNotes note, ref string result);
27 #endregion Notes
28
29 #region Profile Properties
30 bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result);
31 bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result);
32 #endregion Profile Properties
33
34 #region Interests
35 bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result);
36 #endregion Interests
37
38 #region Utility
39 OSD AvatarImageAssetsRequest(UUID avatarId);
40 #endregion Utility
41
42 #region UserData
43 bool RequestUserAppData(ref UserAppData prop, ref string result);
44 bool SetUserAppData(UserAppData prop, ref string result);
45 #endregion UserData
46 }
47}
48
diff --git a/OpenSim/Services/UserProfilesService/UserProfilesService.cs b/OpenSim/Services/UserProfilesService/UserProfilesService.cs
new file mode 100644
index 0000000..959c661
--- /dev/null
+++ b/OpenSim/Services/UserProfilesService/UserProfilesService.cs
@@ -0,0 +1,160 @@
1using System;
2using System.Reflection;
3using System.Text;
4using Nini.Config;
5using log4net;
6using OpenSim.Server.Base;
7using OpenSim.Services.Interfaces;
8using OpenSim.Services.UserAccountService;
9using OpenSim.Data;
10using OpenMetaverse;
11using OpenMetaverse.StructuredData;
12using OpenSim.Framework;
13
14namespace OpenSim.Services.ProfilesService
15{
16 public class UserProfilesService: UserProfilesServiceBase, IUserProfilesService
17 {
18 static readonly ILog m_log =
19 LogManager.GetLogger(
20 MethodBase.GetCurrentMethod().DeclaringType);
21
22 IUserAccountService userAccounts;
23 IAuthenticationService authService;
24
25 public UserProfilesService(IConfigSource config, string configName):
26 base(config, configName)
27 {
28 IConfig Config = config.Configs[configName];
29 if (Config == null)
30 {
31 m_log.Warn("[PROFILES]: No configuration found!");
32 return;
33 }
34 Object[] args = null;
35
36 args = new Object[] { config };
37 string accountService = Config.GetString("UserAccountService", String.Empty);
38 if (accountService != string.Empty)
39 userAccounts = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
40
41 args = new Object[] { config };
42 string authServiceConfig = Config.GetString("AuthenticationServiceModule", String.Empty);
43 if (accountService != string.Empty)
44 authService = ServerUtils.LoadPlugin<IAuthenticationService>(authServiceConfig, args);
45 }
46
47 #region Classifieds
48 public OSD AvatarClassifiedsRequest(UUID creatorId)
49 {
50 OSDArray records = ProfilesData.GetClassifiedRecords(creatorId);
51
52 return records;
53 }
54
55 public bool ClassifiedUpdate(UserClassifiedAdd ad, ref string result)
56 {
57 if(!ProfilesData.UpdateClassifiedRecord(ad, ref result))
58 {
59 return false;
60 }
61 result = "success";
62 return true;
63 }
64
65 public bool ClassifiedDelete(UUID recordId)
66 {
67 if(ProfilesData.DeleteClassifiedRecord(recordId))
68 return true;
69
70 return false;
71 }
72
73 public bool ClassifiedInfoRequest(ref UserClassifiedAdd ad, ref string result)
74 {
75 if(ProfilesData.GetClassifiedInfo(ref ad, ref result))
76 return true;
77
78 return false;
79 }
80 #endregion Classifieds
81
82 #region Picks
83 public OSD AvatarPicksRequest(UUID creatorId)
84 {
85 OSDArray records = ProfilesData.GetAvatarPicks(creatorId);
86
87 return records;
88 }
89
90 public bool PickInfoRequest(ref UserProfilePick pick, ref string result)
91 {
92 pick = ProfilesData.GetPickInfo(pick.CreatorId, pick.PickId);
93 result = "OK";
94 return true;
95 }
96
97 public bool PicksUpdate(ref UserProfilePick pick, ref string result)
98 {
99 return ProfilesData.UpdatePicksRecord(pick);
100 }
101
102 public bool PicksDelete(UUID pickId)
103 {
104 return ProfilesData.DeletePicksRecord(pickId);
105 }
106 #endregion Picks
107
108 #region Notes
109 public bool AvatarNotesRequest(ref UserProfileNotes note)
110 {
111 return ProfilesData.GetAvatarNotes(ref note);
112 }
113
114 public bool NotesUpdate(ref UserProfileNotes note, ref string result)
115 {
116 return ProfilesData.UpdateAvatarNotes(ref note, ref result);
117 }
118 #endregion Notes
119
120 #region Profile Properties
121 public bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result)
122 {
123 return ProfilesData.GetAvatarProperties(ref prop, ref result);
124 }
125
126 public bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result)
127 {
128 return ProfilesData.UpdateAvatarProperties(ref prop, ref result);
129 }
130 #endregion Profile Properties
131
132 #region Interests
133 public bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result)
134 {
135 return ProfilesData.UpdateAvatarInterests(prop, ref result);
136 }
137 #endregion Interests
138
139 #region Utility
140 public OSD AvatarImageAssetsRequest(UUID avatarId)
141 {
142 OSDArray records = ProfilesData.GetUserImageAssets(avatarId);
143 return records;
144 }
145 #endregion Utility
146
147 #region UserData
148 public bool RequestUserAppData(ref UserAppData prop, ref string result)
149 {
150 return ProfilesData.GetUserAppData(ref prop, ref result);
151 }
152
153 public bool SetUserAppData(UserAppData prop, ref string result)
154 {
155 return true;
156 }
157 #endregion UserData
158 }
159}
160
diff --git a/OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs b/OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs
new file mode 100644
index 0000000..dc0be03
--- /dev/null
+++ b/OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs
@@ -0,0 +1,59 @@
1using System;
2using System.Reflection;
3using Nini.Config;
4using log4net;
5using OpenSim.Services.Base;
6using OpenSim.Data;
7
8namespace OpenSim.Services.ProfilesService
9{
10 public class UserProfilesServiceBase: ServiceBase
11 {
12 static readonly ILog m_log =
13 LogManager.GetLogger(
14 MethodBase.GetCurrentMethod().DeclaringType);
15
16 public IProfilesData ProfilesData;
17
18 public string ConfigName
19 {
20 get; private set;
21 }
22
23 public UserProfilesServiceBase(IConfigSource config, string configName):
24 base(config)
25 {
26 if(string.IsNullOrEmpty(configName))
27 {
28 m_log.WarnFormat("[PROFILES]: Configuration section not given!");
29 return;
30 }
31
32 string dllName = String.Empty;
33 string connString = null;
34 string realm = String.Empty;
35
36 IConfig dbConfig = config.Configs["DatabaseService"];
37 if (dbConfig != null)
38 {
39 if (dllName == String.Empty)
40 dllName = dbConfig.GetString("StorageProvider", String.Empty);
41 if (string.IsNullOrEmpty(connString))
42 connString = dbConfig.GetString("ConnectionString", String.Empty);
43 }
44
45 IConfig ProfilesConfig = config.Configs[configName];
46 if (ProfilesConfig != null)
47 {
48 connString = ProfilesConfig.GetString("ConnectionString", connString);
49 realm = ProfilesConfig.GetString("Realm", realm);
50 }
51
52 ProfilesData = LoadPlugin<IProfilesData>(dllName, new Object[] { connString });
53 if (ProfilesData == null)
54 throw new Exception("Could not find a storage interface in the given module");
55
56 }
57 }
58}
59
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 5e486d4..38e2a07 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1032,6 +1032,12 @@
1032 ;# {InitialTerrain} {} {Initial terrain type} {pinhead-island flat} pinhead-island 1032 ;# {InitialTerrain} {} {Initial terrain type} {pinhead-island flat} pinhead-island
1033 ; InitialTerrain = "pinhead-island" 1033 ; InitialTerrain = "pinhead-island"
1034 1034
1035[Profile]
1036 ;# {ProfileURL} {} {Set url to UserProfilesService} {}
1037 ;; Set the value of the url to your UserProfilesService
1038 ;; If un-set / "" the module is disabled
1039 ;; ProfileURL = http://127.0.0.1:8002
1040
1035[Architecture] 1041[Architecture]
1036 ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini 1042 ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini
1037 ;; Uncomment one of the following includes as required. For instance, to create a standalone OpenSim, 1043 ;; Uncomment one of the following includes as required. For instance, to create a standalone OpenSim,
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 81843b1..237f684 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -377,6 +377,19 @@
377 AllowRegionRestartFromClient = true 377 AllowRegionRestartFromClient = true
378 378
379 379
380[UserProfiles]
381 ;# {ProfileURL} {} {Set url to UserProfilesService} {}
382 ;; Set the value of the url to your UserProfilesService
383 ;; If un-set / "" the module is disabled
384 ;; If the ProfileURL is not set, then very BASIC
385 ;; profile support will be configured. If the ProfileURL is set to a
386 ;; valid URL, then full profile support will be configured. The URL
387 ;; points to your grid's Robust user profiles service
388 ;;
389 ; ProfileURL = http://127.0.0.1:9000
390
391
392
380[SMTP] 393[SMTP]
381 enabled = false 394 enabled = false
382 395
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index bc2b4cf..d9f1ca1 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -71,10 +71,12 @@ HGInventoryServiceConnector = "HGInventoryService@8002/OpenSim.Server.Handlers.d
71HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector" 71HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector"
72;; Uncomment this if you want Groups V2, HG to work 72;; Uncomment this if you want Groups V2, HG to work
73; HGGroupsServiceConnector = "8002/OpenSim.Addons.Groups.dll:HGGroupsServiceRobustConnector" 73; HGGroupsServiceConnector = "8002/OpenSim.Addons.Groups.dll:HGGroupsServiceRobustConnector"
74
75;; Additions for other add-on modules. For example: 74;; Additions for other add-on modules. For example:
76;; WifiServerConnector = "8002/Diva.Wifi.dll:WifiServerConnector" 75;; WifiServerConnector = "8002/Diva.Wifi.dll:WifiServerConnector"
77 76
77;; Uncomment for UserProfiles see [UserProfilesService] to configure...
78; UserProfilesServiceConnector = "8002/OpenSim.Server.Handlers.dll:UserProfilesConnector"
79
78; * This is common for all services, it's the network setup for the entire 80; * This is common for all services, it's the network setup for the entire
79; * server instance, if none is specified above 81; * server instance, if none is specified above
80; * 82; *
@@ -595,4 +597,12 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset
595 ;; Can overwrite the default in [Hypergrid], but probably shouldn't 597 ;; Can overwrite the default in [Hypergrid], but probably shouldn't
596 ; HomeURI = "http://127.0.0.1:8002" 598 ; HomeURI = "http://127.0.0.1:8002"
597 599
600[UserProfilesService]
601 LocalServiceModule = "OpenSim.Services.UserProfilesService.dll:UserProfilesService"
602 Enabled = false
603 ;; Configure this for separate profiles database
604 ;; ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=*****;Old Guids=true;"
605 ;; Realm = UserProfiles
606 UserAccountService = OpenSim.Services.UserAccountService.dll:UserAccountService
607 AuthenticationServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
598 608
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example
index 1d66b7f..7d6492b 100644
--- a/bin/Robust.ini.example
+++ b/bin/Robust.ini.example
@@ -51,6 +51,8 @@ MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnecto
51;; Uncomment this if you want Groups V2 to work 51;; Uncomment this if you want Groups V2 to work
52;GroupsServiceConnector = "8003/OpenSim.Addons.Groups.dll:GroupsServiceRobustConnector" 52;GroupsServiceConnector = "8003/OpenSim.Addons.Groups.dll:GroupsServiceRobustConnector"
53 53
54;; Uncomment for UserProfiles see [UserProfilesService] to configure...
55; UserProfilesServiceConnector = "8002/OpenSim.Server.Handlers.dll:UserProfilesConnector"
54 56
55; * This is common for all services, it's the network setup for the entire 57; * This is common for all services, it's the network setup for the entire
56; * server instance, if none is specified above 58; * server instance, if none is specified above
@@ -391,4 +393,13 @@ MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnecto
391 ; password help: optional: page providing password assistance for users of your grid 393 ; password help: optional: page providing password assistance for users of your grid
392 ;password = http://127.0.0.1/password 394 ;password = http://127.0.0.1/password
393 395
396[UserProfilesService]
397 LocalServiceModule = "OpenSim.Services.UserProfilesService.dll:UserProfilesService"
398 Enabled = false
399 ;; Configure this for separate profiles database
400 ;; ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=*****;Old Guids=true;"
401 ;; Realm = UserProfiles
402 UserAccountService = OpenSim.Services.UserAccountService.dll:UserAccountService
403 AuthenticationServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
404
394 405
diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example
index 2547244..8c23c41 100644
--- a/bin/config-include/StandaloneCommon.ini.example
+++ b/bin/config-include/StandaloneCommon.ini.example
@@ -352,3 +352,19 @@
352 ;; If appearance is restricted, which accounts' appearances are allowed to be exported? 352 ;; If appearance is restricted, which accounts' appearances are allowed to be exported?
353 ;; Comma-separated list of account names 353 ;; Comma-separated list of account names
354 AccountForAppearance = "Test User, Astronaut Smith" 354 AccountForAppearance = "Test User, Astronaut Smith"
355
356;; UserProfiles Service
357;;
358;; To use, set Enabled to true then configure for your site...
359[UserProfilesService]
360 LocalServiceModule = "OpenSim.Services.UserProfilesService.dll:UserProfilesService"
361 Enabled = false
362
363 ;; Configure this for separate databse
364 ; ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;"
365 ; Realm = UserProfiles
366
367 UserAccountService = OpenSim.Services.UserAccountService.dll:UserAccountService
368 AuthenticationServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
369
370
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini
index ba92030..39c33e8 100644
--- a/bin/config-include/StandaloneHypergrid.ini
+++ b/bin/config-include/StandaloneHypergrid.ini
@@ -19,6 +19,7 @@
19 GridUserServices = "LocalGridUserServicesConnector" 19 GridUserServices = "LocalGridUserServicesConnector"
20 SimulationServices = "RemoteSimulationConnectorModule" 20 SimulationServices = "RemoteSimulationConnectorModule"
21 AvatarServices = "LocalAvatarServicesConnector" 21 AvatarServices = "LocalAvatarServicesConnector"
22 UserProfilesServices = "LocalUserProfilesServicesConnector"
22 MapImageService = "MapImageServiceModule" 23 MapImageService = "MapImageServiceModule"
23 EntityTransferModule = "HGEntityTransferModule" 24 EntityTransferModule = "HGEntityTransferModule"
24 InventoryAccessModule = "HGInventoryAccessModule" 25 InventoryAccessModule = "HGInventoryAccessModule"
@@ -184,7 +185,6 @@
184 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" 185 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
185 InGatekeeper = True 186 InGatekeeper = True
186 187
187
188;; This should always be the very last thing on this file 188;; This should always be the very last thing on this file
189[Includes] 189[Includes]
190 Include-Common = "config-include/StandaloneCommon.ini" 190 Include-Common = "config-include/StandaloneCommon.ini"
diff --git a/prebuild.xml b/prebuild.xml
index 5967ef6..03cac76 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -281,6 +281,7 @@
281 <Reference name="System.Data"/> 281 <Reference name="System.Data"/>
282 <Reference name="XMLRPC" path="../../bin/"/> 282 <Reference name="XMLRPC" path="../../bin/"/>
283 <Reference name="OpenMetaverse" path="../../bin/"/> 283 <Reference name="OpenMetaverse" path="../../bin/"/>
284 <Reference name="OpenMetaverse.StructuredData" path="../../bin/"/>
284 <Reference name="OpenMetaverseTypes" path="../../bin/"/> 285 <Reference name="OpenMetaverseTypes" path="../../bin/"/>
285 <Reference name="OpenSim.Framework"/> 286 <Reference name="OpenSim.Framework"/>
286 <Reference name="log4net" path="../../bin/"/> 287 <Reference name="log4net" path="../../bin/"/>
@@ -1239,6 +1240,42 @@
1239 </Files> 1240 </Files>
1240 </Project> 1241 </Project>
1241 1242
1243 <Project frameworkVersion="v3_5" name="OpenSim.Services.UserProfilesService" path="OpenSim/Services/UserProfilesService" type="Library">
1244 <Configuration name="Debug">
1245 <Options>
1246 <OutputPath>../../../bin/</OutputPath>
1247 </Options>
1248 </Configuration>
1249 <Configuration name="Release">
1250 <Options>
1251 <OutputPath>../../../bin/</OutputPath>
1252 </Options>
1253 </Configuration>
1254
1255 <ReferencePath>../../../bin/</ReferencePath>
1256 <Reference name="System"/>
1257 <Reference name="System.Core"/>
1258 <Reference name="OpenSim.Framework"/>
1259 <Reference name="OpenSim.Framework.Console"/>
1260 <Reference name="OpenSim.Framework.Servers.HttpServer"/>
1261 <Reference name="OpenSim.Services.UserAccountService"/>
1262 <Reference name="OpenSim.Services.Interfaces"/>
1263 <Reference name="OpenSim.Services.Connectors"/>
1264 <Reference name="OpenSim.Services.Base"/>
1265 <Reference name="OpenSim.Server.Base"/>
1266 <Reference name="OpenSim.Data"/>
1267 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
1268 <Reference name="OpenMetaverse" path="../../../bin/"/>
1269 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
1270 <Reference name="Nini" path="../../../bin/"/>
1271 <Reference name="log4net" path="../../../bin/"/>
1272
1273 <Files>
1274 <Match pattern="*.cs" recurse="true"/>
1275 </Files>
1276 </Project>
1277
1278
1242 <Project frameworkVersion="v3_5" name="OpenSim.Server.Handlers" path="OpenSim/Server/Handlers" type="Library"> 1279 <Project frameworkVersion="v3_5" name="OpenSim.Server.Handlers" path="OpenSim/Server/Handlers" type="Library">
1243 <Configuration name="Debug"> 1280 <Configuration name="Debug">
1244 <Options> 1281 <Options>
@@ -1977,6 +2014,7 @@
1977 <Reference name="OpenSim.Data"/> 2014 <Reference name="OpenSim.Data"/>
1978 <Reference name="OpenMetaverseTypes" path="../../../bin/"/> 2015 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
1979 <Reference name="OpenMetaverse" path="../../../bin/"/> 2016 <Reference name="OpenMetaverse" path="../../../bin/"/>
2017 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
1980 <Reference name="MySql.Data" path="../../../bin/"/> 2018 <Reference name="MySql.Data" path="../../../bin/"/>
1981 <Reference name="OpenSim.Framework.Console"/> 2019 <Reference name="OpenSim.Framework.Console"/>
1982 <Reference name="OpenSim.Region.Framework"/> 2020 <Reference name="OpenSim.Region.Framework"/>