From 8f9a726465c5bb7528d6ae7d74f20818d4ee3094 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 30 May 2013 19:27:20 +0100
Subject: If on a sit request we sit the avatar on a different prim in a
linkset for some reason (e.g. because it has a sit target), then send the
actual sit prim UUID to the viewer rather than the requested one.
This purports to fix the issue described in http://opensimulator.org/mantis/view.php?id=6653 where the camera can end up following the requested sit prim rather than the actual.
The original spot was by Vegaslon, this commit just goes about it in a slightly different way
This commit also makes m_requestedSitTargetUUID to be the actual UUID, which is consistent with m_requestedSitTargetID which was already doing this.
However, this adjustment has no practical effect since we only currently need to know that there's any requested sit UUID at all, not which one it is.
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ab7fd5b..e8aa52e 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2138,9 +2138,9 @@ namespace OpenSim.Region.Framework.Scenes
forceMouselook = part.GetForceMouselook();
ControllingClient.SendSitResponse(
- targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
+ part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
- m_requestedSitTargetUUID = targetID;
+ m_requestedSitTargetUUID = part.UUID;
HandleAgentSit(ControllingClient, UUID);
@@ -2165,7 +2165,7 @@ namespace OpenSim.Region.Framework.Scenes
if (part != null)
{
m_requestedSitTargetID = part.LocalId;
- m_requestedSitTargetUUID = targetID;
+ m_requestedSitTargetUUID = part.UUID;
// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
--
cgit v1.1
From 12a3b855619735b2e36a67ab99027029c8b57260 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 30 May 2013 22:20:02 +0100
Subject: Fix passing of voice distance attenuation to the Vivox voice server.
Because of a typo, this wasn't being done at all - now the 'default' value as described in OpenSimDefaults.ini of 10m is passed (vivox_channel_clamping_distance)
Thanks to Ai Austin for spotting this.
---
.../Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index db4869d..2d65530 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -836,7 +836,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff);
requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel);
requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange);
- requrl = String.Format("{0}&chan_ckamping_distance={1}", requrl, m_vivoxChannelClampingDistance);
+ requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance);
XmlElement resp = VivoxCall(requrl, true);
if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri))
--
cgit v1.1
From 6b88a665d3a3196288b5aa16eb23f7673c2433ac Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 30 May 2013 22:43:52 +0100
Subject: minor: fix warnings in GodsModule that were due to duplicate using
statements
---
OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 16673ec..a542d62 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -26,29 +26,25 @@
*/
using System;
-using System.Collections.Generic;
-using Nini.Config;
-using OpenMetaverse;
-using OpenSim.Framework;
-using OpenSim.Region.Framework.Scenes;
-using OpenSim.Region.Framework.Interfaces;
-using System;
-using System.Reflection;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
-using System.Reflection;
using System.IO;
+using System.Reflection;
using System.Web;
using System.Xml;
using log4net;
-
using Mono.Addins;
-
+using Nini.Config;
+using OpenMetaverse;
using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData;
+using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Region.Framework.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
--
cgit v1.1
From 328883700a15e4216bf7b251ac099d38f413375e Mon Sep 17 00:00:00 2001
From: BlueWall
Date: Mon, 13 May 2013 22:11:28 -0400
Subject: UserProfiles
UserProfiles for Robust and Standalone. Includes service and connectors for Robust and standalone opensim plus matching region module.
---
OpenSim/Data/IProfilesData.cs | 29 +
OpenSim/Data/MySQL/MySQLUserProfilesData.cs | 1023 +++++++++++++++
.../Data/MySQL/Resources/UserProfiles.migrations | 83 ++
OpenSim/Framework/UserProfiles.cs | 90 ++
.../Avatar/Profile/BasicProfileModule.cs | 176 ---
.../Avatar/UserProfiles/UserProfileModule.cs | 1386 ++++++++++++++++++++
.../LocalUserProfilesServiceConnector.cs | 226 ++++
.../Grid/LocalGridServiceConnector.cs | 1 +
.../Handlers/Profiles/UserProfilesConnector.cs | 92 ++
.../Handlers/Profiles/UserProfilesHandlers.cs | 434 ++++++
.../Services/Interfaces/IUserProfilesService.cs | 48 +
.../UserProfilesService/UserProfilesService.cs | 160 +++
.../UserProfilesService/UserProfilesServiceBase.cs | 59 +
13 files changed, 3631 insertions(+), 176 deletions(-)
create mode 100644 OpenSim/Data/IProfilesData.cs
create mode 100644 OpenSim/Data/MySQL/MySQLUserProfilesData.cs
create mode 100644 OpenSim/Data/MySQL/Resources/UserProfiles.migrations
create mode 100644 OpenSim/Framework/UserProfiles.cs
delete mode 100644 OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
create mode 100644 OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs
create mode 100644 OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs
create mode 100644 OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs
create mode 100644 OpenSim/Services/Interfaces/IUserProfilesService.cs
create mode 100644 OpenSim/Services/UserProfilesService/UserProfilesService.cs
create mode 100644 OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs
(limited to 'OpenSim')
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 @@
+using System;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework;
+
+namespace OpenSim.Data
+{
+
+ public interface IProfilesData
+ {
+ OSDArray GetClassifiedRecords(UUID creatorId);
+ bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result);
+ bool DeleteClassifiedRecord(UUID recordId);
+ OSDArray GetAvatarPicks(UUID avatarId);
+ UserProfilePick GetPickInfo(UUID avatarId, UUID pickId);
+ bool UpdatePicksRecord(UserProfilePick pick);
+ bool DeletePicksRecord(UUID pickId);
+ bool GetAvatarNotes(ref UserProfileNotes note);
+ bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result);
+ bool GetAvatarProperties(ref UserProfileProperties props, ref string result);
+ bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
+ bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
+ bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
+ bool GetUserAppData(ref UserAppData props, ref string result);
+ bool SetUserAppData(UserAppData props, ref string result);
+ OSDArray GetUserImageAssets(UUID avatarId);
+ }
+}
+
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 @@
+using System;
+using System.Data;
+using System.Reflection;
+using OpenSim.Data;
+using OpenSim.Framework;
+using MySql.Data.MySqlClient;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using log4net;
+
+namespace OpenSim.Data.MySQL
+{
+ public class UserProfilesData: IProfilesData
+ {
+ static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ #region Properites
+ string ConnectionString
+ {
+ get; set;
+ }
+
+ protected object Lock
+ {
+ get; set;
+ }
+
+ protected virtual Assembly Assembly
+ {
+ get { return GetType().Assembly; }
+ }
+
+ #endregion Properties
+
+ #region class Member Functions
+ public UserProfilesData(string connectionString)
+ {
+ ConnectionString = connectionString;
+ Init();
+ }
+
+ void Init()
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+
+ Migration m = new Migration(dbcon, Assembly, "UserProfiles");
+ m.Update();
+ }
+ }
+ #endregion Member Functions
+
+ #region Classifieds Queries
+ ///
+ /// Gets the classified records.
+ ///
+ ///
+ /// Array of classified records
+ ///
+ ///
+ /// Creator identifier.
+ ///
+ public OSDArray GetClassifiedRecords(UUID creatorId)
+ {
+ OSDArray data = new OSDArray();
+
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id";
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", creatorId);
+ using( MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
+ {
+ if(reader.HasRows)
+ {
+ while (reader.Read())
+ {
+ OSDMap n = new OSDMap();
+ UUID Id = UUID.Zero;
+
+ string Name = null;
+ try
+ {
+ UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id);
+ Name = Convert.ToString(reader["name"]);
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": UserAccount exception {0}", e.Message);
+ }
+ n.Add("classifieduuid", OSD.FromUUID(Id));
+ n.Add("name", OSD.FromString(Name));
+ data.Add(n);
+ }
+ }
+ }
+ }
+ }
+ return data;
+ }
+
+ public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result)
+ {
+ string query = string.Empty;
+
+
+ query += "INSERT INTO classifieds (";
+ query += "`classifieduuid`,";
+ query += "`creatoruuid`,";
+ query += "`creationdate`,";
+ query += "`expirationdate`,";
+ query += "`category`,";
+ query += "`name`,";
+ query += "`description`,";
+ query += "`parceluuid`,";
+ query += "`parentestate`,";
+ query += "`snapshotuuid`,";
+ query += "`simname`,";
+ query += "`posglobal`,";
+ query += "`parcelname`,";
+ query += "`classifiedflags`,";
+ query += "`priceforlisting`) ";
+ query += "VALUES (";
+ query += "?ClassifiedId,";
+ query += "?CreatorId,";
+ query += "?CreatedDate,";
+ query += "?ExpirationDate,";
+ query += "?Category,";
+ query += "?Name,";
+ query += "?Description,";
+ query += "?ParcelId,";
+ query += "?ParentEstate,";
+ query += "?SnapshotId,";
+ query += "?SimName,";
+ query += "?GlobalPos,";
+ query += "?ParcelName,";
+ query += "?Flags,";
+ query += "?ListingPrice ) ";
+ query += "ON DUPLICATE KEY UPDATE ";
+ query += "category=?Category, ";
+ query += "expirationdate=?ExpirationDate, ";
+ query += "name=?Name, ";
+ query += "description=?Description, ";
+ query += "parentestate=?ParentEstate, ";
+ query += "posglobal=?GlobalPos, ";
+ query += "parcelname=?ParcelName, ";
+ query += "classifiedflags=?Flags, ";
+ query += "priceforlisting=?ListingPrice, ";
+ query += "snapshotuuid=?SnapshotId";
+
+ if(string.IsNullOrEmpty(ad.ParcelName))
+ ad.ParcelName = "Unknown";
+ if(ad.ParcelId == null)
+ ad.ParcelId = UUID.Zero;
+ if(string.IsNullOrEmpty(ad.Description))
+ ad.Description = "No Description";
+
+ DateTime epoch = new DateTime(1970, 1, 1);
+ DateTime now = DateTime.Now;
+ TimeSpan epochnow = now - epoch;
+ TimeSpan duration;
+ DateTime expiration;
+ TimeSpan epochexp;
+
+ if(ad.Flags == 2)
+ {
+ duration = new TimeSpan(7,0,0,0);
+ expiration = now.Add(duration);
+ epochexp = expiration - epoch;
+ }
+ else
+ {
+ duration = new TimeSpan(365,0,0,0);
+ expiration = now.Add(duration);
+ epochexp = expiration - epoch;
+ }
+ ad.CreationDate = (int)epochnow.TotalSeconds;
+ ad.ExpirationDate = (int)epochexp.TotalSeconds;
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?ClassifiedId", ad.ClassifiedId.ToString());
+ cmd.Parameters.AddWithValue("?CreatorId", ad.CreatorId.ToString());
+ cmd.Parameters.AddWithValue("?CreatedDate", ad.CreationDate.ToString());
+ cmd.Parameters.AddWithValue("?ExpirationDate", ad.ExpirationDate.ToString());
+ cmd.Parameters.AddWithValue("?Category", ad.Category.ToString());
+ cmd.Parameters.AddWithValue("?Name", ad.Name.ToString());
+ cmd.Parameters.AddWithValue("?Description", ad.Description.ToString());
+ cmd.Parameters.AddWithValue("?ParcelId", ad.ParcelId.ToString());
+ cmd.Parameters.AddWithValue("?ParentEstate", ad.ParentEstate.ToString());
+ cmd.Parameters.AddWithValue("?SnapshotId", ad.SnapshotId.ToString ());
+ cmd.Parameters.AddWithValue("?SimName", ad.SimName.ToString());
+ cmd.Parameters.AddWithValue("?GlobalPos", ad.GlobalPos.ToString());
+ cmd.Parameters.AddWithValue("?ParcelName", ad.ParcelName.ToString());
+ cmd.Parameters.AddWithValue("?Flags", ad.Flags.ToString());
+ cmd.Parameters.AddWithValue("?ListingPrice", ad.Price.ToString ());
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": ClassifiedesUpdate exception {0}", e.Message);
+ result = e.Message;
+ return false;
+ }
+ return true;
+ }
+
+ public bool DeleteClassifiedRecord(UUID recordId)
+ {
+ string query = string.Empty;
+
+ query += "DELETE FROM classifieds WHERE ";
+ query += "classifieduuid = ?ClasifiedId";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?ClassifiedId", recordId.ToString());
+
+ lock(Lock)
+ {
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": DeleteClassifiedRecord exception {0}", e.Message);
+ return false;
+ }
+ return true;
+ }
+
+ public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result)
+ {
+ string query = string.Empty;
+
+ query += "SELECT * FROM classifieds WHERE ";
+ query += "classifieduuid = ?AdId";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?AdId", ad.ClassifiedId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader())
+ {
+ if(reader.Read ())
+ {
+ ad.CreatorId = new UUID(reader.GetGuid("creatoruuid"));
+ ad.ParcelId = new UUID(reader.GetGuid("parceluuid"));
+ ad.SnapshotId = new UUID(reader.GetGuid("snapshotuuid"));
+ ad.CreationDate = Convert.ToInt32(reader["creationdate"]);
+ ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]);
+ ad.ParentEstate = Convert.ToInt32(reader["parentestate"]);
+ ad.Flags = (byte)reader.GetUInt32("classifiedflags");
+ ad.Category = reader.GetInt32("category");
+ ad.Price = reader.GetInt16("priceforlisting");
+ ad.Name = reader.GetString("name");
+ ad.Description = reader.GetString("description");
+ ad.SimName = reader.GetString("simname");
+ ad.GlobalPos = reader.GetString("posglobal");
+ ad.ParcelName = reader.GetString("parcelname");
+
+ }
+ }
+ }
+ dbcon.Close();
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": GetPickInfo exception {0}", e.Message);
+ }
+ return true;
+ }
+ #endregion Classifieds Queries
+
+ #region Picks Queries
+ public OSDArray GetAvatarPicks(UUID avatarId)
+ {
+ string query = string.Empty;
+
+ query += "SELECT `pickuuid`,`name` FROM userpicks WHERE ";
+ query += "creatoruuid = ?Id";
+ OSDArray data = new OSDArray();
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader())
+ {
+ if(reader.HasRows)
+ {
+ while (reader.Read())
+ {
+ OSDMap record = new OSDMap();
+
+ record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"]));
+ record.Add("name",OSD.FromString((string)reader["name"]));
+ data.Add(record);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": GetAvatarPicks exception {0}", e.Message);
+ }
+ return data;
+ }
+
+ public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId)
+ {
+ string query = string.Empty;
+ UserProfilePick pick = new UserProfilePick();
+
+ query += "SELECT * FROM userpicks WHERE ";
+ query += "creatoruuid = ?CreatorId AND ";
+ query += "pickuuid = ?PickId";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?CreatorId", avatarId.ToString());
+ cmd.Parameters.AddWithValue("?PickId", pickId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader())
+ {
+ if(reader.HasRows)
+ {
+ reader.Read();
+
+ string description = (string)reader["description"];
+
+ if (string.IsNullOrEmpty(description))
+ description = "No description given.";
+
+ UUID.TryParse((string)reader["pickuuid"], out pick.PickId);
+ UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId);
+ UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
+ UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
+ pick.GlobalPos = (string)reader["posglobal"];
+ bool.TryParse((string)reader["toppick"], out pick.TopPick);
+ bool.TryParse((string)reader["enabled"], out pick.Enabled);
+ pick.Name = (string)reader["name"];
+ pick.Desc = description;
+ pick.User = (string)reader["user"];
+ pick.OriginalName = (string)reader["originalname"];
+ pick.SimName = (string)reader["simname"];
+ pick.SortOrder = (int)reader["sortorder"];
+ }
+ }
+ }
+ dbcon.Close();
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": GetPickInfo exception {0}", e.Message);
+ }
+ return pick;
+ }
+
+ public bool UpdatePicksRecord(UserProfilePick pick)
+ {
+ string query = string.Empty;
+
+ query += "INSERT INTO userpicks VALUES (";
+ query += "?PickId,";
+ query += "?CreatorId,";
+ query += "?TopPick,";
+ query += "?ParcelId,";
+ query += "?Name,";
+ query += "?Desc,";
+ query += "?SnapshotId,";
+ query += "?User,";
+ query += "?Original,";
+ query += "?SimName,";
+ query += "?GlobalPos,";
+ query += "?SortOrder,";
+ query += "?Enabled) ";
+ query += "ON DUPLICATE KEY UPDATE ";
+ query += "parceluuid=?ParcelId,";
+ query += "name=?Name,";
+ query += "description=?Desc,";
+ query += "snapshotuuid=?SnapshotId,";
+ query += "pickuuid=?PickId,";
+ query += "posglobal=?GlobalPos";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?PickId", pick.PickId.ToString());
+ cmd.Parameters.AddWithValue("?CreatorId", pick.CreatorId.ToString());
+ cmd.Parameters.AddWithValue("?TopPick", pick.TopPick.ToString());
+ cmd.Parameters.AddWithValue("?ParcelId", pick.ParcelId.ToString());
+ cmd.Parameters.AddWithValue("?Name", pick.Name.ToString());
+ cmd.Parameters.AddWithValue("?Desc", pick.Desc.ToString());
+ cmd.Parameters.AddWithValue("?SnapshotId", pick.SnapshotId.ToString());
+ cmd.Parameters.AddWithValue("?User", pick.User.ToString());
+ cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString());
+ cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString());
+ cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos);
+ cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ());
+ cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString());
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": UpdateAvatarNotes exception {0}", e.Message);
+ return false;
+ }
+ return true;
+ }
+
+ public bool DeletePicksRecord(UUID pickId)
+ {
+ string query = string.Empty;
+
+ query += "DELETE FROM userpicks WHERE ";
+ query += "pickuuid = ?PickId";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?PickId", pickId.ToString());
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": DeleteUserPickRecord exception {0}", e.Message);
+ return false;
+ }
+ return true;
+ }
+ #endregion Picks Queries
+
+ #region Avatar Notes Queries
+ public bool GetAvatarNotes(ref UserProfileNotes notes)
+ { // WIP
+ string query = string.Empty;
+
+ query += "SELECT `notes` FROM usernotes WHERE ";
+ query += "useruuid = ?Id AND ";
+ query += "targetuuid = ?TargetId";
+ OSDArray data = new OSDArray();
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", notes.UserId.ToString());
+ cmd.Parameters.AddWithValue("?TargetId", notes.TargetId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
+ {
+ if(reader.HasRows)
+ {
+ reader.Read();
+ notes.Notes = OSD.FromString((string)reader["notes"]);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": GetAvatarNotes exception {0}", e.Message);
+ }
+ return true;
+ }
+
+ public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result)
+ {
+ string query = string.Empty;
+ bool remove;
+
+ if(string.IsNullOrEmpty(note.Notes))
+ {
+ remove = true;
+ query += "DELETE FROM usernotes WHERE ";
+ query += "useruuid=?UserId AND ";
+ query += "targetuuid=?TargetId";
+ }
+ else
+ {
+ remove = false;
+ query += "INSERT INTO usernotes VALUES ( ";
+ query += "?UserId,";
+ query += "?TargetId,";
+ query += "?Notes )";
+ query += "ON DUPLICATE KEY ";
+ query += "UPDATE ";
+ query += "notes=?Notes";
+ }
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ if(!remove)
+ cmd.Parameters.AddWithValue("?Notes", note.Notes);
+ cmd.Parameters.AddWithValue("?TargetId", note.TargetId.ToString ());
+ cmd.Parameters.AddWithValue("?UserId", note.UserId.ToString());
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": UpdateAvatarNotes exception {0}", e.Message);
+ return false;
+ }
+ return true;
+
+ }
+ #endregion Avatar Notes Queries
+
+ #region Avatar Properties
+ public bool GetAvatarProperties(ref UserProfileProperties props, ref string result)
+ {
+ string query = string.Empty;
+
+ query += "SELECT * FROM userprofile WHERE ";
+ query += "useruuid = ?Id";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", props.UserId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
+ {
+ if(reader.HasRows)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": Getting data for {0}.", props.UserId);
+ reader.Read();
+ props.WebUrl = (string)reader["profileURL"];
+ UUID.TryParse((string)reader["profileImage"], out props.ImageId);
+ props.AboutText = (string)reader["profileAboutText"];
+ UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId);
+ props.FirstLifeText = (string)reader["profileFirstText"];
+ UUID.TryParse((string)reader["profilePartner"], out props.PartnerId);
+ props.WantToMask = (int)reader["profileWantToMask"];
+ props.WantToText = (string)reader["profileWantToText"];
+ props.SkillsMask = (int)reader["profileSkillsMask"];
+ props.SkillsText = (string)reader["profileSkillsText"];
+ props.Language = (string)reader["profileLanguages"];
+ }
+ else
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": No data for {0}", props.UserId);
+
+ props.WebUrl = string.Empty;
+ props.ImageId = UUID.Zero;
+ props.AboutText = string.Empty;
+ props.FirstLifeImageId = UUID.Zero;
+ props.FirstLifeText = string.Empty;
+ props.PartnerId = UUID.Zero;
+ props.WantToMask = 0;
+ props.WantToText = string.Empty;
+ props.SkillsMask = 0;
+ props.SkillsText = string.Empty;
+ props.Language = string.Empty;
+
+ query = "INSERT INTO userprofile (`useruuid`) VALUES (?userId)";
+
+ dbcon.Close();
+ dbcon.Open();
+
+ using (MySqlCommand put = new MySqlCommand(query, dbcon))
+ {
+ put.Parameters.AddWithValue("?userId", props.UserId.ToString());
+ put.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": Requst properties exception {0}", e.Message);
+ result = e.Message;
+ return false;
+ }
+ return true;
+ }
+
+ public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result)
+ {
+ string query = string.Empty;
+
+ query += "UPDATE userprofile SET ";
+ query += "profileURL=?profileURL, ";
+ query += "profileImage=?image, ";
+ query += "profileAboutText=?abouttext,";
+ query += "profileFirstImage=?firstlifeimage,";
+ query += "profileFirstText=?firstlifetext ";
+ query += "WHERE useruuid=?uuid";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?profileURL", props.WebUrl);
+ cmd.Parameters.AddWithValue("?image", props.ImageId.ToString());
+ cmd.Parameters.AddWithValue("?abouttext", props.AboutText);
+ cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString());
+ cmd.Parameters.AddWithValue("?firstlifetext", props.FirstLifeText);
+ cmd.Parameters.AddWithValue("?uuid", props.UserId.ToString());
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": AgentPropertiesUpdate exception {0}", e.Message);
+
+ return false;
+ }
+ return true;
+ }
+ #endregion Avatar Properties
+
+ #region Avatar Interests
+ public bool UpdateAvatarInterests(UserProfileProperties up, ref string result)
+ {
+ string query = string.Empty;
+
+ query += "UPDATE userprofile SET ";
+ query += "profileWantToMask=?WantMask, ";
+ query += "profileWantToText=?WantText,";
+ query += "profileSkillsMask=?SkillsMask,";
+ query += "profileSkillsText=?SkillsText, ";
+ query += "profileLanguages=?Languages ";
+ query += "WHERE useruuid=?uuid";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?WantMask", up.WantToMask);
+ cmd.Parameters.AddWithValue("?WantText", up.WantToText);
+ cmd.Parameters.AddWithValue("?SkillsMask", up.SkillsMask);
+ cmd.Parameters.AddWithValue("?SkillsText", up.SkillsText);
+ cmd.Parameters.AddWithValue("?Languages", up.Language);
+ cmd.Parameters.AddWithValue("?uuid", up.UserId.ToString());
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": AgentInterestsUpdate exception {0}", e.Message);
+ result = e.Message;
+ return false;
+ }
+ return true;
+ }
+ #endregion Avatar Interests
+
+ public OSDArray GetUserImageAssets(UUID avatarId)
+ {
+ OSDArray data = new OSDArray();
+ string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id";
+
+ // Get classified image assets
+
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+
+ using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`classifieds`"), dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
+ {
+ if(reader.HasRows)
+ {
+ while (reader.Read())
+ {
+ data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
+ }
+ }
+ }
+ }
+
+ dbcon.Close();
+ dbcon.Open();
+
+ using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
+ {
+ if(reader.HasRows)
+ {
+ while (reader.Read())
+ {
+ data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
+ }
+ }
+ }
+ }
+
+ dbcon.Close();
+ dbcon.Open();
+
+ query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id";
+
+ using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
+ {
+ if(reader.HasRows)
+ {
+ while (reader.Read())
+ {
+ data.Add(new OSDString((string)reader["profileImage"].ToString ()));
+ data.Add(new OSDString((string)reader["profileFirstImage"].ToString ()));
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": GetAvatarNotes exception {0}", e.Message);
+ }
+ return data;
+ }
+
+ #region User Preferences
+ public OSDArray GetUserPreferences(UUID avatarId)
+ {
+ string query = string.Empty;
+
+ query += "SELECT imviaemail,visible,email FROM ";
+ query += "usersettings WHERE ";
+ query += "useruuid = ?Id";
+
+ OSDArray data = new OSDArray();
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", avatarId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader())
+ {
+ if(reader.HasRows)
+ {
+ reader.Read();
+ OSDMap record = new OSDMap();
+
+ record.Add("imviaemail",OSD.FromString((string)reader["imviaemail"]));
+ record.Add("visible",OSD.FromString((string)reader["visible"]));
+ record.Add("email",OSD.FromString((string)reader["email"]));
+ data.Add(record);
+ }
+ else
+ {
+ using (MySqlCommand put = new MySqlCommand(query, dbcon))
+ {
+ query = "INSERT INTO usersettings VALUES ";
+ query += "(?Id,'false','false', '')";
+
+ lock(Lock)
+ {
+ put.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": Get preferences exception {0}", e.Message);
+ }
+ return data;
+ }
+
+ public bool UpdateUserPreferences(bool emailIm, bool visible, UUID avatarId )
+ {
+ string query = string.Empty;
+
+ query += "UPDATE userpsettings SET ";
+ query += "imviaemail=?ImViaEmail, ";
+ query += "visible=?Visible,";
+ query += "WHERE useruuid=?uuid";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?ImViaEmail", emailIm.ToString().ToLower ());
+ cmd.Parameters.AddWithValue("?WantText", visible.ToString().ToLower ());
+ cmd.Parameters.AddWithValue("?uuid", avatarId.ToString());
+
+ lock(Lock)
+ {
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": AgentInterestsUpdate exception {0}", e.Message);
+ return false;
+ }
+ return true;
+ }
+ #endregion User Preferences
+
+ #region Integration
+ public bool GetUserAppData(ref UserAppData props, ref string result)
+ {
+ string query = string.Empty;
+
+ query += "SELECT * FROM `userdata` WHERE ";
+ query += "UserId = ?Id AND ";
+ query += "TagId = ?TagId";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?Id", props.UserId.ToString());
+ cmd.Parameters.AddWithValue ("?TagId", props.TagId.ToString());
+
+ using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
+ {
+ if(reader.HasRows)
+ {
+ reader.Read();
+ props.DataKey = (string)reader["DataKey"];
+ props.DataVal = (string)reader["DataVal"];
+ }
+ else
+ {
+ query += "INSERT INTO userdata VALUES ( ";
+ query += "?UserId,";
+ query += "?TagId,";
+ query += "?DataKey,";
+ query += "?DataVal) ";
+
+ using (MySqlCommand put = new MySqlCommand(query, dbcon))
+ {
+ put.Parameters.AddWithValue("?Id", props.UserId.ToString());
+ put.Parameters.AddWithValue("?TagId", props.TagId.ToString());
+ put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
+ put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString());
+
+ lock(Lock)
+ {
+ put.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": Requst application data exception {0}", e.Message);
+ result = e.Message;
+ return false;
+ }
+ return true;
+ }
+
+ public bool SetUserAppData(UserAppData props, ref string result)
+ {
+ string query = string.Empty;
+
+ query += "UPDATE userdata SET ";
+ query += "TagId = ?TagId, ";
+ query += "DataKey = ?DataKey, ";
+ query += "DataVal = ?DataVal WHERE ";
+ query += "UserId = ?UserId AND ";
+ query += "TagId = ?TagId";
+
+ try
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(ConnectionString))
+ {
+ dbcon.Open();
+ using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
+ {
+ cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString());
+ cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString ());
+ cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString ());
+ cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString ());
+
+ lock(Lock)
+ {
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[PROFILES_DATA]" +
+ ": SetUserData exception {0}", e.Message);
+ return false;
+ }
+ return true;
+ }
+ #endregion Integration
+ }
+}
+
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 @@
+:VERSION 1 # -------------------------------
+
+begin;
+
+CREATE TABLE IF NOT EXISTS `classifieds` (
+ `classifieduuid` char(36) NOT NULL,
+ `creatoruuid` char(36) NOT NULL,
+ `creationdate` int(20) NOT NULL,
+ `expirationdate` int(20) NOT NULL,
+ `category` varchar(20) NOT NULL,
+ `name` varchar(255) NOT NULL,
+ `description` text NOT NULL,
+ `parceluuid` char(36) NOT NULL,
+ `parentestate` int(11) NOT NULL,
+ `snapshotuuid` char(36) NOT NULL,
+ `simname` varchar(255) NOT NULL,
+ `posglobal` varchar(255) NOT NULL,
+ `parcelname` varchar(255) NOT NULL,
+ `classifiedflags` int(8) NOT NULL,
+ `priceforlisting` int(5) NOT NULL,
+ PRIMARY KEY (`classifieduuid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+CREATE TABLE IF NOT EXISTS `usernotes` (
+ `useruuid` varchar(36) NOT NULL,
+ `targetuuid` varchar(36) NOT NULL,
+ `notes` text NOT NULL,
+ UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+CREATE TABLE IF NOT EXISTS `userpicks` (
+ `pickuuid` varchar(36) NOT NULL,
+ `creatoruuid` varchar(36) NOT NULL,
+ `toppick` enum('true','false') NOT NULL,
+ `parceluuid` varchar(36) NOT NULL,
+ `name` varchar(255) NOT NULL,
+ `description` text NOT NULL,
+ `snapshotuuid` varchar(36) NOT NULL,
+ `user` varchar(255) NOT NULL,
+ `originalname` varchar(255) NOT NULL,
+ `simname` varchar(255) NOT NULL,
+ `posglobal` varchar(255) NOT NULL,
+ `sortorder` int(2) NOT NULL,
+ `enabled` enum('true','false') NOT NULL,
+ PRIMARY KEY (`pickuuid`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+CREATE TABLE IF NOT EXISTS `userprofile` (
+ `useruuid` varchar(36) NOT NULL,
+ `profilePartner` varchar(36) NOT NULL,
+ `profileAllowPublish` binary(1) NOT NULL,
+ `profileMaturePublish` binary(1) NOT NULL,
+ `profileURL` varchar(255) NOT NULL,
+ `profileWantToMask` int(3) NOT NULL,
+ `profileWantToText` text NOT NULL,
+ `profileSkillsMask` int(3) NOT NULL,
+ `profileSkillsText` text NOT NULL,
+ `profileLanguages` text NOT NULL,
+ `profileImage` varchar(36) NOT NULL,
+ `profileAboutText` text NOT NULL,
+ `profileFirstImage` varchar(36) NOT NULL,
+ `profileFirstText` text NOT NULL,
+ PRIMARY KEY (`useruuid`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+commit;
+
+:VERSION 2 # -------------------------------
+
+begin;
+CREATE TABLE IF NOT EXISTS `userdata` (
+ `UserId` char(36) NOT NULL,
+ `TagId` varchar(64) NOT NULL,
+ `DataKey` varchar(255),
+ `DataVal` varchar(255),
+ PRIMARY KEY (`UserId`,`TagId`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+commit;
+
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 @@
+using System;
+using OpenMetaverse;
+
+namespace OpenSim.Framework
+{
+ public class UserClassifiedAdd
+ {
+ public UUID ClassifiedId = UUID.Zero;
+ public UUID CreatorId = UUID.Zero;
+ public int CreationDate = 0;
+ public int ExpirationDate = 0;
+ public int Category = 0;
+ public string Name = string.Empty;
+ public string Description = string.Empty;
+ public UUID ParcelId = UUID.Zero;
+ public int ParentEstate = 0;
+ public UUID SnapshotId = UUID.Zero;
+ public string SimName = string.Empty;
+ public string GlobalPos = "<0,0,0>";
+ public string ParcelName = string.Empty;
+ public byte Flags = 0;
+ public int Price = 0;
+ }
+
+ public class UserProfileProperties
+ {
+ public UUID UserId = UUID.Zero;
+ public UUID PartnerId = UUID.Zero;
+ public bool PublishProfile = false;
+ public bool PublishMature = false;
+ public string WebUrl = string.Empty;
+ public int WantToMask = 0;
+ public string WantToText = string.Empty;
+ public int SkillsMask = 0;
+ public string SkillsText = string.Empty;
+ public string Language = string.Empty;
+ public UUID ImageId = UUID.Zero;
+ public string AboutText = string.Empty;
+ public UUID FirstLifeImageId = UUID.Zero;
+ public string FirstLifeText = string.Empty;
+ }
+
+ public class UserProfilePick
+ {
+ public UUID PickId = UUID.Zero;
+ public UUID CreatorId = UUID.Zero;
+ public bool TopPick = false;
+ public string Name = string.Empty;
+ public string OriginalName = string.Empty;
+ public string Desc = string.Empty;
+ public UUID ParcelId = UUID.Zero;
+ public UUID SnapshotId = UUID.Zero;
+ public string User = string.Empty;
+ public string SimName = string.Empty;
+ public string GlobalPos = "<0,0,0>";
+ public int SortOrder = 0;
+ public bool Enabled = false;
+ }
+
+ public class UserProfileNotes
+ {
+ public UUID UserId;
+ public UUID TargetId;
+ public string Notes;
+ }
+
+ public class UserAccountProperties
+ {
+ public string EmailAddress = string.Empty;
+ public string Firstname = string.Empty;
+ public string LastName = string.Empty;
+ public string Password = string.Empty;
+ public string UserId = string.Empty;
+ }
+
+ public class UserAccountAuth
+ {
+ public string UserId = UUID.Zero.ToString();
+ public string Password = string.Empty;
+ }
+
+ public class UserAppData
+ {
+ public string TagId = string.Empty;
+ public string DataKey = string.Empty;
+ public string UserId = UUID.Zero.ToString();
+ public string DataVal = string.Empty;
+ }
+}
+
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 @@
-/*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Reflection;
-
-using OpenMetaverse;
-using log4net;
-using Nini.Config;
-using Mono.Addins;
-
-using OpenSim.Framework;
-using OpenSim.Region.Framework.Interfaces;
-using OpenSim.Region.Framework.Scenes;
-using OpenSim.Services.Interfaces;
-
-namespace OpenSim.Region.CoreModules.Avatar.Profile
-{
- [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicProfileModule")]
- public class BasicProfileModule : IProfileModule, ISharedRegionModule
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
- //
- // Module vars
- //
- private List m_Scenes = new List();
- private bool m_Enabled = false;
-
- #region ISharedRegionModule
-
- public void Initialise(IConfigSource config)
- {
- m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
- m_Enabled = true;
- }
-
- public void AddRegion(Scene scene)
- {
- if (!m_Enabled)
- return;
-
- lock (m_Scenes)
- {
- if (!m_Scenes.Contains(scene))
- {
- m_Scenes.Add(scene);
- // Hook up events
- scene.EventManager.OnNewClient += OnNewClient;
- scene.RegisterModuleInterface(this);
- }
- }
- }
-
- public void RegionLoaded(Scene scene)
- {
- if (!m_Enabled)
- return;
- }
-
- public void RemoveRegion(Scene scene)
- {
- if (!m_Enabled)
- return;
-
- lock (m_Scenes)
- {
- m_Scenes.Remove(scene);
- }
- }
-
- public void PostInitialise()
- {
- }
-
- public void Close()
- {
- }
-
- public string Name
- {
- get { return "BasicProfileModule"; }
- }
-
- public Type ReplaceableInterface
- {
- get { return typeof(IProfileModule); }
- }
-
- #endregion
-
- /// New Client Event Handler
- private void OnNewClient(IClientAPI client)
- {
- //Profile
- client.OnRequestAvatarProperties += RequestAvatarProperties;
- }
-
- public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
- {
- IScene s = remoteClient.Scene;
- if (!(s is Scene))
- return;
-
-// Scene scene = (Scene)s;
-
- string profileUrl = String.Empty;
- string aboutText = String.Empty;
- string firstLifeAboutText = String.Empty;
- UUID image = UUID.Zero;
- UUID firstLifeImage = UUID.Zero;
- UUID partner = UUID.Zero;
- uint wantMask = 0;
- string wantText = String.Empty;
- uint skillsMask = 0;
- string skillsText = String.Empty;
- string languages = String.Empty;
-
- UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, avatarID);
-
- string name = "Avatar";
- int created = 0;
- if (account != null)
- {
- name = account.FirstName + " " + account.LastName;
- created = account.Created;
- }
- Byte[] charterMember = Utils.StringToBytes(name);
-
- profileUrl = "No profile data";
- aboutText = string.Empty;
- firstLifeAboutText = string.Empty;
- image = UUID.Zero;
- firstLifeImage = UUID.Zero;
- partner = UUID.Zero;
-
- remoteClient.SendAvatarProperties(avatarID, aboutText,
- Util.ToDateTime(created).ToString(
- "M/d/yyyy", CultureInfo.InvariantCulture),
- charterMember, firstLifeAboutText,
- (uint)(0 & 0xff),
- firstLifeImage, image, profileUrl, partner);
-
- //Viewer expects interest data when it asks for properties.
- remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
- skillsMask, skillsText, languages);
- }
-
- }
-}
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 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.IO;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Net;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Xml;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using log4net;
+using Nini.Config;
+using Nwc.XmlRpc;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Services.Interfaces;
+using Mono.Addins;
+using OpenSim.Services.Connectors.Hypergrid;
+
+namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")]
+ public class UserProfileModule : IProfileModule, INonSharedRegionModule
+ {
+ ///
+ /// Logging
+ ///
+ static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ // The pair of Dictionaries are used to handle the switching of classified ads
+ // by maintaining a cache of classified id to creator id mappings and an interest
+ // count. The entries are removed when the interest count reaches 0.
+ Dictionary classifiedCache = new Dictionary();
+ Dictionary classifiedInterest = new Dictionary();
+
+ public Scene Scene
+ {
+ get; private set;
+ }
+
+ ///
+ /// Gets or sets the ConfigSource.
+ ///
+ ///
+ /// The configuration
+ ///
+ public IConfigSource Config {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets the URI to the profile server.
+ ///
+ ///
+ /// The profile server URI.
+ ///
+ public string ProfileServerUri {
+ get;
+ set;
+ }
+
+ IProfileModule ProfileModule
+ {
+ get; set;
+ }
+
+ IUserManagement UserManagementModule
+ {
+ get; set;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether this
+ /// is enabled.
+ ///
+ ///
+ /// true if enabled; otherwise, false.
+ ///
+ public bool Enabled {
+ get;
+ set;
+ }
+
+ #region IRegionModuleBase implementation
+ ///
+ /// This is called to initialize the region module. For shared modules, this is called exactly once, after
+ /// creating the single (shared) instance. For non-shared modules, this is called once on each instance, after
+ /// the instace for the region has been created.
+ ///
+ ///
+ /// Source.
+ ///
+ public void Initialise(IConfigSource source)
+ {
+ Config = source;
+
+ IConfig profileConfig = Config.Configs["Profile"];
+
+ if (profileConfig == null)
+ {
+ Enabled = false;
+ return;
+ }
+
+ // If we find ProfileURL then we configure for FULL support
+ // else we setup for BASIC support
+ ProfileServerUri = profileConfig.GetString("ProfileURL", "");
+ if (ProfileServerUri == "")
+ {
+ m_log.Info("[PROFILES] UserProfiles module is activated in BASIC mode");
+ Enabled = false;
+ return;
+ }
+ else
+ {
+ m_log.Info("[PROFILES] UserProfiles module is activated in FULL mode");
+ Enabled = true;
+ }
+ }
+
+ ///
+ /// Adds the region.
+ ///
+ ///
+ /// Scene.
+ ///
+ public void AddRegion(Scene scene)
+ {
+ Scene = scene;
+ Scene.RegisterModuleInterface(this);
+ Scene.EventManager.OnNewClient += OnNewClient;
+ Scene.EventManager.OnMakeRootAgent += HandleOnMakeRootAgent;
+
+ UserManagementModule = Scene.RequestModuleInterface();
+ }
+
+ void HandleOnMakeRootAgent (ScenePresence obj)
+ {
+ GetImageAssets(((IScenePresence)obj).UUID);
+ }
+
+ ///
+ /// Removes the region.
+ ///
+ ///
+ /// Scene.
+ ///
+ public void RemoveRegion(Scene scene)
+ {
+ }
+
+ ///
+ /// This will be called once for every scene loaded. In a shared module this will be multiple times in one
+ /// instance, while a nonshared module instance will only be called once. This method is called after AddRegion
+ /// has been called in all modules for that scene, providing an opportunity to request another module's
+ /// interface, or hook an event from another module.
+ ///
+ ///
+ /// Scene.
+ ///
+ public void RegionLoaded(Scene scene)
+ {
+ }
+
+ ///
+ /// If this returns non-null, it is the type of an interface that this module intends to register. This will
+ /// cause the loader to defer loading of this module until all other modules have been loaded. If no other
+ /// module has registered the interface by then, this module will be activated, else it will remain inactive,
+ /// letting the other module take over. This should return non-null ONLY in modules that are intended to be
+ /// easily replaceable, e.g. stub implementations that the developer expects to be replaced by third party
+ /// provided modules.
+ ///
+ ///
+ /// The replaceable interface.
+ ///
+ public Type ReplaceableInterface
+ {
+ get { return typeof(IProfileModule); }
+ }
+
+ ///
+ /// Called as the instance is closed.
+ ///
+ public void Close()
+ {
+ }
+
+ ///
+ /// The name of the module
+ ///
+ ///
+ /// Gets the module name.
+ ///
+ public string Name
+ {
+ get { return "UserProfileModule"; }
+ }
+ #endregion IRegionModuleBase implementation
+
+ #region Region Event Handlers
+ ///
+ /// Raises the new client event.
+ ///
+ ///
+ /// Client.
+ ///
+ void OnNewClient(IClientAPI client)
+ {
+ // Basic or Full module?
+ if(!Enabled)
+ {
+ client.OnRequestAvatarProperties += BasicRequestProperties;
+ return;
+ }
+
+ //Profile
+ client.OnRequestAvatarProperties += RequestAvatarProperties;
+ client.OnUpdateAvatarProperties += AvatarPropertiesUpdate;
+ client.OnAvatarInterestUpdate += AvatarInterestsUpdate;
+
+ // Classifieds
+ client.AddGenericPacketHandler("avatarclassifiedsrequest", ClassifiedsRequest);
+ client.OnClassifiedInfoUpdate += ClassifiedInfoUpdate;
+ client.OnClassifiedInfoRequest += ClassifiedInfoRequest;
+ client.OnClassifiedDelete += ClassifiedDelete;
+
+ // Picks
+ client.AddGenericPacketHandler("avatarpicksrequest", PicksRequest);
+ client.AddGenericPacketHandler("pickinforequest", PickInfoRequest);
+ client.OnPickInfoUpdate += PickInfoUpdate;
+ client.OnPickDelete += PickDelete;
+
+ // Notes
+ client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest);
+ client.OnAvatarNotesUpdate += NotesUpdate;
+ }
+ #endregion Region Event Handlers
+
+ #region Classified
+ ///
+ ///
+ /// Handles the avatar classifieds request.
+ ///
+ ///
+ /// Sender.
+ ///
+ ///
+ /// Method.
+ ///
+ ///
+ /// Arguments.
+ ///
+ public void ClassifiedsRequest(Object sender, string method, List args)
+ {
+ if (!(sender is IClientAPI))
+ return;
+
+ IClientAPI remoteClient = (IClientAPI)sender;
+
+ UUID targetID;
+ UUID.TryParse(args[0], out targetID);
+
+ // Can't handle NPC yet...
+ ScenePresence p = FindPresence(targetID);
+
+ if (null != p)
+ {
+ if (p.PresenceType == PresenceType.Npc)
+ return;
+ }
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(targetID, out serverURI);
+ UUID creatorId = UUID.Zero;
+
+ OSDMap parameters= new OSDMap();
+ UUID.TryParse(args[0], out creatorId);
+ parameters.Add("creatorId", OSD.FromUUID(creatorId));
+ OSD Params = (OSD)parameters;
+ if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString()))
+ {
+ // Error Handling here!
+ // if(parameters.ContainsKey("message")
+ }
+
+ parameters = (OSDMap)Params;
+
+ OSDArray list = (OSDArray)parameters["result"];
+
+ Dictionary classifieds = new Dictionary();
+
+ foreach(OSD map in list)
+ {
+ OSDMap m = (OSDMap)map;
+ UUID cid = m["classifieduuid"].AsUUID();
+ string name = m["name"].AsString();
+
+ classifieds[cid] = name;
+
+ if(!classifiedCache.ContainsKey(cid))
+ {
+ classifiedCache.Add(cid,creatorId);
+ classifiedInterest.Add(cid, 0);
+ }
+
+ classifiedInterest[cid] ++;
+ }
+
+ remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds);
+ }
+
+ public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient)
+ {
+ UUID target = remoteClient.AgentId;
+ UserClassifiedAdd ad = new UserClassifiedAdd();
+ ad.ClassifiedId = queryClassifiedID;
+
+ if(classifiedCache.ContainsKey(queryClassifiedID))
+ {
+ target = classifiedCache[queryClassifiedID];
+
+ if(classifiedInterest[queryClassifiedID] -- == 0)
+ {
+ lock(classifiedCache)
+ {
+ lock(classifiedInterest)
+ {
+ classifiedInterest.Remove(queryClassifiedID);
+ }
+ classifiedCache.Remove(queryClassifiedID);
+ }
+ }
+ }
+
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(target, out serverURI);
+
+ object Ad = (object)ad;
+ if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error getting classified info", false);
+ return;
+ }
+ ad = (UserClassifiedAdd) Ad;
+
+ if(ad.CreatorId == UUID.Zero)
+ return;
+
+ Vector3 globalPos = new Vector3();
+ Vector3.TryParse(ad.GlobalPos, out globalPos);
+
+ remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate, (uint)ad.ExpirationDate,
+ (uint)ad.Category, ad.Name, ad.Description, ad.ParcelId, (uint)ad.ParentEstate,
+ ad.SnapshotId, ad.SimName, globalPos, ad.ParcelName, ad.Flags, ad.Price);
+
+ }
+
+ ///
+ /// Classifieds info update.
+ ///
+ ///
+ /// Queryclassified I.
+ ///
+ ///
+ /// Query category.
+ ///
+ ///
+ /// Query name.
+ ///
+ ///
+ /// Query description.
+ ///
+ ///
+ /// Query parcel I.
+ ///
+ ///
+ /// Query parent estate.
+ ///
+ ///
+ /// Query snapshot I.
+ ///
+ ///
+ /// Query global position.
+ ///
+ ///
+ /// Queryclassified flags.
+ ///
+ ///
+ /// Queryclassified price.
+ ///
+ ///
+ /// Remote client.
+ ///
+ public void ClassifiedInfoUpdate(UUID queryclassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID,
+ uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags,
+ int queryclassifiedPrice, IClientAPI remoteClient)
+ {
+ UserClassifiedAdd ad = new UserClassifiedAdd();
+
+ Scene s = (Scene) remoteClient.Scene;
+ Vector3 pos = remoteClient.SceneAgent.AbsolutePosition;
+ ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y);
+ ScenePresence p = FindPresence(remoteClient.AgentId);
+ Vector3 avaPos = p.AbsolutePosition;
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+
+ if (land == null)
+ {
+ ad.ParcelName = string.Empty;
+ }
+ else
+ {
+ ad.ParcelName = land.LandData.Name;
+ }
+
+ ad.CreatorId = remoteClient.AgentId;
+ ad.ClassifiedId = queryclassifiedID;
+ ad.Category = Convert.ToInt32(queryCategory);
+ ad.Name = queryName;
+ ad.Description = queryDescription;
+ ad.ParentEstate = Convert.ToInt32(queryParentEstate);
+ ad.SnapshotId = querySnapshotID;
+ ad.SimName = remoteClient.Scene.RegionInfo.RegionName;
+ ad.GlobalPos = queryGlobalPos.ToString ();
+ ad.Flags = queryclassifiedFlags;
+ ad.Price = queryclassifiedPrice;
+ ad.ParcelId = p.currentParcelUUID;
+
+ object Ad = ad;
+
+ OSD X = OSD.SerializeMembers(Ad);
+
+ if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error updating classified", false);
+ }
+ }
+
+ ///
+ /// Classifieds delete.
+ ///
+ ///
+ /// Query classified I.
+ ///
+ ///
+ /// Remote client.
+ ///
+ public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient)
+ {
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+
+ UUID classifiedId;
+ OSDMap parameters= new OSDMap();
+ UUID.TryParse(queryClassifiedID.ToString(), out classifiedId);
+ parameters.Add("classifiedId", OSD.FromUUID(classifiedId));
+ OSD Params = (OSD)parameters;
+ if(!JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error classified delete", false);
+ }
+
+ parameters = (OSDMap)Params;
+ }
+ #endregion Classified
+
+ #region Picks
+ ///
+ /// Handles the avatar picks request.
+ ///
+ ///
+ /// Sender.
+ ///
+ ///
+ /// Method.
+ ///
+ ///
+ /// Arguments.
+ ///
+ public void PicksRequest(Object sender, string method, List args)
+ {
+ if (!(sender is IClientAPI))
+ return;
+
+ IClientAPI remoteClient = (IClientAPI)sender;
+
+ UUID targetId;
+ UUID.TryParse(args[0], out targetId);
+
+ // Can't handle NPC yet...
+ ScenePresence p = FindPresence(targetId);
+
+ if (null != p)
+ {
+ if (p.PresenceType == PresenceType.Npc)
+ return;
+ }
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(targetId, out serverURI);
+
+ OSDMap parameters= new OSDMap();
+ parameters.Add("creatorId", OSD.FromUUID(targetId));
+ OSD Params = (OSD)parameters;
+ if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error requesting picks", false);
+ return;
+ }
+
+ parameters = (OSDMap)Params;
+
+ OSDArray list = (OSDArray)parameters["result"];
+
+ Dictionary picks = new Dictionary();
+
+ foreach(OSD map in list)
+ {
+ OSDMap m = (OSDMap)map;
+ UUID cid = m["pickuuid"].AsUUID();
+ string name = m["name"].AsString();
+
+ m_log.DebugFormat("[PROFILES]: PicksRequest {0}", name);
+
+ picks[cid] = name;
+ }
+ remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks);
+ }
+
+ ///
+ /// Handles the pick info request.
+ ///
+ ///
+ /// Sender.
+ ///
+ ///
+ /// Method.
+ ///
+ ///
+ /// Arguments.
+ ///
+ public void PickInfoRequest(Object sender, string method, List args)
+ {
+ if (!(sender is IClientAPI))
+ return;
+
+ UUID targetID;
+ UUID.TryParse(args[0], out targetID);
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(targetID, out serverURI);
+ IClientAPI remoteClient = (IClientAPI)sender;
+
+ UserProfilePick pick = new UserProfilePick();
+ UUID.TryParse(args[0], out pick.CreatorId);
+ UUID.TryParse(args[1], out pick.PickId);
+
+
+ object Pick = (object)pick;
+ if(!JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error selecting pick", false);
+ }
+ pick = (UserProfilePick) Pick;
+ if(pick.SnapshotId == UUID.Zero)
+ {
+ // In case of a new UserPick, the data may not be ready and we would send wrong data, skip it...
+ m_log.DebugFormat("[PROFILES]: PickInfoRequest: SnapshotID is {0}", UUID.Zero.ToString());
+ return;
+ }
+
+ Vector3 globalPos;
+ Vector3.TryParse(pick.GlobalPos,out globalPos);
+
+ m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
+
+ remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
+ pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName,
+ globalPos,pick.SortOrder,pick.Enabled);
+ }
+
+ ///
+ /// Updates the userpicks
+ ///
+ ///
+ /// Remote client.
+ ///
+ ///
+ /// Pick I.
+ ///
+ ///
+ /// the creator of the pick
+ ///
+ ///
+ /// Top pick.
+ ///
+ ///
+ /// Name.
+ ///
+ ///
+ /// Desc.
+ ///
+ ///
+ /// Snapshot I.
+ ///
+ ///
+ /// Sort order.
+ ///
+ ///
+ /// Enabled.
+ ///
+ public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled)
+ {
+
+ m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
+ UserProfilePick pick = new UserProfilePick();
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+ ScenePresence p = FindPresence(remoteClient.AgentId);
+
+ Vector3 avaPos = p.AbsolutePosition;
+ // Getting the global position for the Avatar
+ Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X,
+ remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y,
+ avaPos.Z);
+
+ string landOwnerName = string.Empty;
+ ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y);
+ if(land.LandData.IsGroupOwned)
+ {
+ IGroupsModule groupMod = p.Scene.RequestModuleInterface();
+ UUID groupId = land.LandData.GroupID;
+ GroupRecord groupRecord = groupMod.GetGroupRecord(groupId);
+ landOwnerName = groupRecord.GroupName;
+ }
+ else
+ {
+ IUserAccountService accounts = p.Scene.RequestModuleInterface();
+ UserAccount user = accounts.GetUserAccount(p.Scene.RegionInfo.ScopeID, land.LandData.OwnerID);
+ landOwnerName = user.Name;
+ }
+
+ pick.PickId = pickID;
+ pick.CreatorId = creatorID;
+ pick.TopPick = topPick;
+ pick.Name = name;
+ pick.Desc = desc;
+ pick.ParcelId = p.currentParcelUUID;
+ pick.SnapshotId = snapshotID;
+ pick.User = landOwnerName;
+ pick.SimName = remoteClient.Scene.RegionInfo.RegionName;
+ pick.GlobalPos = posGlobal.ToString();
+ pick.SortOrder = sortOrder;
+ pick.Enabled = enabled;
+
+ object Pick = (object)pick;
+ if(!JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error updating pick", false);
+ }
+
+ m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString());
+ }
+
+ ///
+ /// Delete a Pick
+ ///
+ ///
+ /// Remote client.
+ ///
+ ///
+ /// Query pick I.
+ ///
+ public void PickDelete(IClientAPI remoteClient, UUID queryPickID)
+ {
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+
+ OSDMap parameters= new OSDMap();
+ parameters.Add("pickId", OSD.FromUUID(queryPickID));
+ OSD Params = (OSD)parameters;
+ if(!JsonRpcRequest(ref Params, "picks_delete", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error picks delete", false);
+ }
+ }
+ #endregion Picks
+
+ #region Notes
+ ///
+ /// Handles the avatar notes request.
+ ///
+ ///
+ /// Sender.
+ ///
+ ///
+ /// Method.
+ ///
+ ///
+ /// Arguments.
+ ///
+ public void NotesRequest(Object sender, string method, List args)
+ {
+ UserProfileNotes note = new UserProfileNotes();
+
+ if (!(sender is IClientAPI))
+ return;
+
+ IClientAPI remoteClient = (IClientAPI)sender;
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+ note.TargetId = remoteClient.AgentId;
+ UUID.TryParse(args[0], out note.UserId);
+
+ object Note = (object)note;
+ if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error requesting note", false);
+ }
+ note = (UserProfileNotes) Note;
+
+ remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes);
+ }
+
+ ///
+ /// Avatars the notes update.
+ ///
+ ///
+ /// Remote client.
+ ///
+ ///
+ /// Query target I.
+ ///
+ ///
+ /// Query notes.
+ ///
+ public void NotesUpdate(IClientAPI remoteClient, UUID queryTargetID, string queryNotes)
+ {
+ UserProfileNotes note = new UserProfileNotes();
+
+ note.UserId = remoteClient.AgentId;
+ note.TargetId = queryTargetID;
+ note.Notes = queryNotes;
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+
+ object Note = note;
+ if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error updating note", false);
+ }
+ }
+ #endregion Notes
+
+ #region Avatar Properties
+ ///
+ /// Update the avatars interests .
+ ///
+ ///
+ /// Remote client.
+ ///
+ ///
+ /// Wantmask.
+ ///
+ ///
+ /// Wanttext.
+ ///
+ ///
+ /// Skillsmask.
+ ///
+ ///
+ /// Skillstext.
+ ///
+ ///
+ /// Languages.
+ ///
+ public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages)
+ {
+ UserProfileProperties prop = new UserProfileProperties();
+
+ prop.UserId = remoteClient.AgentId;
+ prop.WantToMask = (int)wantmask;
+ prop.WantToText = wanttext;
+ prop.SkillsMask = (int)skillsmask;
+ prop.SkillsText = skillstext;
+ prop.Language = languages;
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+
+ object Param = prop;
+ if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error updating interests", false);
+ }
+ }
+
+ public void BasicRequestProperties(IClientAPI remoteClient, UUID avatarID)
+ {
+ IScene s = remoteClient.Scene;
+ if (!(s is Scene))
+ return;
+
+ string profileUrl = String.Empty;
+ string aboutText = String.Empty;
+ string firstLifeAboutText = String.Empty;
+ UUID image = UUID.Zero;
+ UUID firstLifeImage = UUID.Zero;
+ UUID partner = UUID.Zero;
+ uint wantMask = 0;
+ string wantText = String.Empty;
+ uint skillsMask = 0;
+ string skillsText = String.Empty;
+ string languages = String.Empty;
+
+ UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID);
+
+ string name = "Avatar";
+ int created = 0;
+ if (account != null)
+ {
+ name = account.FirstName + " " + account.LastName;
+ created = account.Created;
+ }
+ Byte[] charterMember = Utils.StringToBytes(name);
+
+ profileUrl = "No profile data";
+ aboutText = string.Empty;
+ firstLifeAboutText = string.Empty;
+ image = UUID.Zero;
+ firstLifeImage = UUID.Zero;
+ partner = UUID.Zero;
+
+ remoteClient.SendAvatarProperties(avatarID, aboutText,
+ Util.ToDateTime(created).ToString(
+ "M/d/yyyy", CultureInfo.InvariantCulture),
+ charterMember, firstLifeAboutText,
+ (uint)(0 & 0xff),
+ firstLifeImage, image, profileUrl, partner);
+
+ //Viewer expects interest data when it asks for properties.
+ remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
+ skillsMask, skillsText, languages);
+ }
+
+ ///
+ /// Requests the avatar properties.
+ ///
+ ///
+ /// Remote client.
+ ///
+ ///
+ /// Avatar I.
+ ///
+ public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
+ {
+ if ( String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString()))
+ {
+ // Looking for a reason that some viewers are sending null Id's
+ m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID);
+ return;
+ }
+
+ // Can't handle NPC yet...
+ ScenePresence p = FindPresence(avatarID);
+
+ if (null != p)
+ {
+ if (p.PresenceType == PresenceType.Npc)
+ return;
+ }
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(avatarID, out serverURI);
+
+ UserAccount account = null;
+ Dictionary userInfo;
+
+ if (!foreign)
+ {
+ account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID);
+ }
+ else
+ {
+ userInfo = new Dictionary();
+ }
+
+ Byte[] charterMember = new Byte[1];
+ string born = String.Empty;
+ uint flags = 0x00;
+
+ if (null != account)
+ {
+ if (account.UserTitle == "")
+ {
+ charterMember[0] = (Byte)((account.UserFlags & 0xf00) >> 8);
+ }
+ else
+ {
+ charterMember = Utils.StringToBytes(account.UserTitle);
+ }
+
+ born = Util.ToDateTime(account.Created).ToString(
+ "M/d/yyyy", CultureInfo.InvariantCulture);
+ flags = (uint)(account.UserFlags & 0xff);
+ }
+ else
+ {
+ if (GetUserAccountData(avatarID, out userInfo) == true)
+ {
+ if ((string)userInfo["user_title"] == "")
+ {
+ charterMember[0] = (Byte)(((Byte)userInfo["user_flags"] & 0xf00) >> 8);
+ }
+ else
+ {
+ charterMember = Utils.StringToBytes((string)userInfo["user_title"]);
+ }
+
+ int val_born = (int)userInfo["user_created"];
+ born = Util.ToDateTime(val_born).ToString(
+ "M/d/yyyy", CultureInfo.InvariantCulture);
+
+ // picky, picky
+ int val_flags = (int)userInfo["user_flags"];
+ flags = (uint)(val_flags & 0xff);
+ }
+ }
+
+ UserProfileProperties props = new UserProfileProperties();
+ string result = string.Empty;
+
+ props.UserId = avatarID;
+ GetProfileData(ref props, out result);
+
+ remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags,
+ props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId);
+
+
+ remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask,
+ props.SkillsText, props.Language);
+ }
+
+ ///
+ /// Updates the avatar properties.
+ ///
+ ///
+ /// Remote client.
+ ///
+ ///
+ /// New profile.
+ ///
+ public void AvatarPropertiesUpdate(IClientAPI remoteClient, UserProfileData newProfile)
+ {
+ if (remoteClient.AgentId == newProfile.ID)
+ {
+ UserProfileProperties prop = new UserProfileProperties();
+
+ prop.UserId = remoteClient.AgentId;
+ prop.WebUrl = newProfile.ProfileUrl;
+ prop.ImageId = newProfile.Image;
+ prop.AboutText = newProfile.AboutText;
+ prop.FirstLifeImageId = newProfile.FirstLifeImage;
+ prop.FirstLifeText = newProfile.FirstLifeAboutText;
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI);
+
+ object Prop = prop;
+
+ if(!JsonRpcRequest(ref Prop, "avatar_properties_update", serverURI, UUID.Random().ToString()))
+ {
+ remoteClient.SendAgentAlertMessage(
+ "Error updating properties", false);
+ }
+
+ RequestAvatarProperties(remoteClient, newProfile.ID);
+ }
+ }
+
+
+ ///
+ /// Gets the profile data.
+ ///
+ ///
+ /// The profile data.
+ ///
+ ///
+ /// User I.
+ ///
+ bool GetProfileData(ref UserProfileProperties properties, out string message)
+ {
+ // Can't handle NPC yet...
+ ScenePresence p = FindPresence(properties.UserId);
+
+ if (null != p)
+ {
+ if (p.PresenceType == PresenceType.Npc)
+ {
+ message = "Id points to NPC";
+ return false;
+ }
+ }
+
+ string serverURI = string.Empty;
+ bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI);
+
+ // This is checking a friend on the home grid
+ // Not HG friend
+ if ( String.IsNullOrEmpty(serverURI))
+ {
+ message = "No Presence - foreign friend";
+ return false;
+ }
+
+ object Prop = (object)properties;
+ JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString());
+ properties = (UserProfileProperties)Prop;
+
+ message = "Success";
+ return true;
+ }
+ #endregion Avatar Properties
+
+ #region Utils
+ bool GetImageAssets(UUID avatarId)
+ {
+ string profileServerURI = string.Empty;
+ string assetServerURI = string.Empty;
+
+ bool foreign = GetUserProfileServerURI(avatarId, out profileServerURI);
+
+ if(!foreign)
+ return true;
+
+ assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI");
+
+ OSDMap parameters= new OSDMap();
+ parameters.Add("avatarId", OSD.FromUUID(avatarId));
+ OSD Params = (OSD)parameters;
+ if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString()))
+ {
+ // Error Handling here!
+ // if(parameters.ContainsKey("message")
+ return false;
+ }
+
+ parameters = (OSDMap)Params;
+
+ OSDArray list = (OSDArray)parameters["result"];
+
+ foreach(OSD asset in list)
+ {
+ OSDString assetId = (OSDString)asset;
+
+ Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString()), this,
+ delegate (string assetID, Object s, AssetBase a)
+ {
+ // m_log.DebugFormat("[PROFILES]: Getting Image Assets {0}", assetID);
+ return;
+ });
+ }
+ return true;
+ }
+
+ ///
+ /// Gets the user account data.
+ ///
+ ///
+ /// The user profile data.
+ ///
+ ///
+ /// If set to true user I.
+ ///
+ ///
+ /// If set to true user info.
+ ///
+ bool GetUserAccountData(UUID userID, out Dictionary userInfo)
+ {
+ Dictionary info = new Dictionary();
+
+ if (UserManagementModule.IsLocalGridUser(userID))
+ {
+ // Is local
+ IUserAccountService uas = Scene.UserAccountService;
+ UserAccount account = uas.GetUserAccount(Scene.RegionInfo.ScopeID, userID);
+
+ info["user_flags"] = account.UserFlags;
+ info["user_created"] = account.Created;
+
+ if (!String.IsNullOrEmpty(account.UserTitle))
+ info["user_title"] = account.UserTitle;
+ else
+ info["user_title"] = "";
+
+ userInfo = info;
+
+ return false;
+ }
+ else
+ {
+ // Is Foreign
+ string home_url = UserManagementModule.GetUserServerURL(userID, "HomeURI");
+
+ if (String.IsNullOrEmpty(home_url))
+ {
+ info["user_flags"] = 0;
+ info["user_created"] = 0;
+ info["user_title"] = "Unavailable";
+
+ userInfo = info;
+ return true;
+ }
+
+ UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url);
+
+ Dictionary account = uConn.GetUserInfo(userID);
+
+ if (account.Count > 0)
+ {
+ if (account.ContainsKey("user_flags"))
+ info["user_flags"] = account["user_flags"];
+ else
+ info["user_flags"] = "";
+
+ if (account.ContainsKey("user_created"))
+ info["user_created"] = account["user_created"];
+ else
+ info["user_created"] = "";
+
+ info["user_title"] = "HG Visitor";
+ }
+ else
+ {
+ info["user_flags"] = 0;
+ info["user_created"] = 0;
+ info["user_title"] = "HG Visitor";
+ }
+ userInfo = info;
+ return true;
+ }
+ }
+
+ ///
+ /// Gets the user profile server UR.
+ ///
+ ///
+ /// The user profile server UR.
+ ///
+ ///
+ /// If set to true user I.
+ ///
+ ///
+ /// If set to true server UR.
+ ///
+ bool GetUserProfileServerURI(UUID userID, out string serverURI)
+ {
+ bool local;
+ local = UserManagementModule.IsLocalGridUser(userID);
+
+ if (!local)
+ {
+ serverURI = UserManagementModule.GetUserServerURL(userID, "ProfileServerURI");
+ // Is Foreign
+ return true;
+ }
+ else
+ {
+ serverURI = ProfileServerUri;
+ // Is local
+ return false;
+ }
+ }
+
+ ///
+ /// Finds the presence.
+ ///
+ ///
+ /// The presence.
+ ///
+ ///
+ /// Client I.
+ ///
+ ScenePresence FindPresence(UUID clientID)
+ {
+ ScenePresence p;
+
+ p = Scene.GetScenePresence(clientID);
+ if (p != null && !p.IsChildAgent)
+ return p;
+
+ return null;
+ }
+ #endregion Util
+
+ #region Web Util
+ ///
+ /// Sends json-rpc request with a serializable type.
+ ///
+ ///
+ /// OSD Map.
+ ///
+ ///
+ /// Serializable type .
+ ///
+ ///
+ /// Json-rpc method to call.
+ ///
+ ///
+ /// URI of json-rpc service.
+ ///
+ ///
+ /// Id for our call.
+ ///
+ bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId)
+ {
+ if (jsonId == null)
+ throw new ArgumentNullException ("jsonId");
+ if (uri == null)
+ throw new ArgumentNullException ("uri");
+ if (method == null)
+ throw new ArgumentNullException ("method");
+ if (parameters == null)
+ throw new ArgumentNullException ("parameters");
+
+ // Prep our payload
+ OSDMap json = new OSDMap();
+
+ json.Add("jsonrpc", OSD.FromString("2.0"));
+ json.Add("id", OSD.FromString(jsonId));
+ json.Add("method", OSD.FromString(method));
+ // Experiment
+ json.Add("params", OSD.SerializeMembers(parameters));
+
+ string jsonRequestData = OSDParser.SerializeJsonString(json);
+ byte[] content = Encoding.UTF8.GetBytes(jsonRequestData);
+
+ HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
+ // webRequest.Credentials = new NetworkCredential(rpcUser, rpcPass);
+ webRequest.ContentType = "application/json-rpc";
+ webRequest.Method = "POST";
+
+ Stream dataStream = webRequest.GetRequestStream();
+ dataStream.Write(content, 0, content.Length);
+ dataStream.Close();
+
+ WebResponse webResponse = null;
+ try
+ {
+ webResponse = webRequest.GetResponse();
+ }
+ catch (WebException e)
+ {
+ Console.WriteLine("Web Error" + e.Message);
+ Console.WriteLine ("Please check input");
+ return false;
+ }
+
+ byte[] buf = new byte[8192];
+ Stream rstream = webResponse.GetResponseStream();
+ OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream);
+
+ if(mret.ContainsKey("error"))
+ return false;
+
+ // get params...
+ OSD.DeserializeMembers(ref parameters, (OSDMap) mret["result"]);
+ return true;
+ }
+
+ ///
+ /// Sends json-rpc request with OSD parameter.
+ ///
+ ///
+ /// The rpc request.
+ ///
+ ///
+ /// data - incoming as parameters, outgong as result/error
+ ///
+ ///
+ /// Json-rpc method to call.
+ ///
+ ///
+ /// URI of json-rpc service.
+ ///
+ ///
+ /// If set to true json identifier.
+ ///
+ bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId)
+ {
+ OSDMap map = new OSDMap();
+
+ map["jsonrpc"] = "2.0";
+ if(string.IsNullOrEmpty(jsonId))
+ map["id"] = UUID.Random().ToString();
+ else
+ map["id"] = jsonId;
+
+ map["method"] = method;
+ map["params"] = data;
+
+ string jsonRequestData = OSDParser.SerializeJsonString(map);
+ byte[] content = Encoding.UTF8.GetBytes(jsonRequestData);
+
+ HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
+ webRequest.ContentType = "application/json-rpc";
+ webRequest.Method = "POST";
+
+ Stream dataStream = webRequest.GetRequestStream();
+ dataStream.Write(content, 0, content.Length);
+ dataStream.Close();
+
+ WebResponse webResponse = null;
+ try
+ {
+ webResponse = webRequest.GetResponse();
+ }
+ catch (WebException e)
+ {
+ Console.WriteLine("Web Error" + e.Message);
+ Console.WriteLine ("Please check input");
+ return false;
+ }
+
+ byte[] buf = new byte[8192];
+ Stream rstream = webResponse.GetResponseStream();
+
+ OSDMap response = new OSDMap();
+ response = (OSDMap)OSDParser.DeserializeJson(rstream);
+ if(response.ContainsKey("error"))
+ {
+ data = response["error"];
+ return false;
+ }
+
+ data = response;
+
+ return true;
+ }
+ #endregion Web Util
+ }
+}
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 @@
+
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using log4net;
+using Mono.Addins;
+using Nini.Config;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Server.Base;
+using OpenSim.Server.Handlers;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Services.Interfaces;
+using GridRegion = OpenSim.Services.Interfaces.GridRegion;
+using OpenMetaverse;
+
+namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalUserProfilesServicesConnector")]
+ public class LocalUserProfilesServicesConnector : ISharedRegionModule
+ {
+ private static readonly ILog m_log =
+ LogManager.GetLogger(
+ MethodBase.GetCurrentMethod().DeclaringType);
+
+ private Dictionary regions = new Dictionary();
+
+ public IUserProfilesService ServiceModule
+ {
+ get; private set;
+ }
+
+ public bool Enabled
+ {
+ get; private set;
+ }
+
+ public string Name
+ {
+ get
+ {
+ return "LocalUserProfilesServicesConnector";
+ }
+ }
+
+ public string ConfigName
+ {
+ get; private set;
+ }
+
+ public Type ReplaceableInterface
+ {
+ get { return null; }
+ }
+
+ public LocalUserProfilesServicesConnector()
+ {
+ m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector no params");
+ }
+
+ public LocalUserProfilesServicesConnector(IConfigSource source)
+ {
+ m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector instantiated directly.");
+ InitialiseService(source);
+ }
+
+ public void InitialiseService(IConfigSource source)
+ {
+ ConfigName = "UserProfilesService";
+
+ // Instantiate the request handler
+ IHttpServer Server = MainServer.Instance;
+
+ IConfig config = source.Configs[ConfigName];
+ if (config == null)
+ {
+ m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: UserProfilesService missing from OpenSim.ini");
+ return;
+ }
+
+ if(!config.GetBoolean("Enabled",false))
+ {
+ Enabled = false;
+ return;
+ }
+
+ Enabled = true;
+
+ string serviceDll = config.GetString("LocalServiceModule",
+ String.Empty);
+
+ if (serviceDll == String.Empty)
+ {
+ m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: No LocalServiceModule named in section UserProfilesService");
+ return;
+ }
+
+ Object[] args = new Object[] { source, ConfigName };
+ ServiceModule =
+ ServerUtils.LoadPlugin(serviceDll,
+ args);
+
+ if (ServiceModule == null)
+ {
+ m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: Can't load user profiles service");
+ return;
+ }
+
+ Enabled = true;
+
+ JsonRpcProfileHandlers handler = new JsonRpcProfileHandlers(ServiceModule);
+
+ Server.AddJsonRPCHandler("avatarclassifiedsrequest", handler.AvatarClassifiedsRequest);
+ Server.AddJsonRPCHandler("classified_update", handler.ClassifiedUpdate);
+ Server.AddJsonRPCHandler("classifieds_info_query", handler.ClassifiedInfoRequest);
+ Server.AddJsonRPCHandler("classified_delete", handler.ClassifiedDelete);
+ Server.AddJsonRPCHandler("avatarpicksrequest", handler.AvatarPicksRequest);
+ Server.AddJsonRPCHandler("pickinforequest", handler.PickInfoRequest);
+ Server.AddJsonRPCHandler("picks_update", handler.PicksUpdate);
+ Server.AddJsonRPCHandler("picks_delete", handler.PicksDelete);
+ Server.AddJsonRPCHandler("avatarnotesrequest", handler.AvatarNotesRequest);
+ Server.AddJsonRPCHandler("avatar_notes_update", handler.NotesUpdate);
+ Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
+ Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
+ Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
+ Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
+ Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
+ Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);
+
+ }
+
+ #region ISharedRegionModule implementation
+
+ void ISharedRegionModule.PostInitialise()
+ {
+ if(!Enabled)
+ return;
+ }
+
+ #endregion
+
+ #region IRegionModuleBase implementation
+
+ void IRegionModuleBase.Initialise(IConfigSource source)
+ {
+ IConfig moduleConfig = source.Configs["Modules"];
+ if (moduleConfig != null)
+ {
+ string name = moduleConfig.GetString("UserProfilesServices", "");
+ if (name == Name)
+ {
+ InitialiseService(source);
+ m_log.Info("[LOCAL USERPROFILES SERVICE CONNECTOR]: Local user profiles connector enabled");
+ }
+ }
+ }
+
+ void IRegionModuleBase.Close()
+ {
+ return;
+ }
+
+ void IRegionModuleBase.AddRegion(Scene scene)
+ {
+ if (!Enabled)
+ return;
+
+ lock (regions)
+ {
+ if (regions.ContainsKey(scene.RegionInfo.RegionID))
+ m_log.ErrorFormat("[LOCAL USERPROFILES SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
+ else
+ regions.Add(scene.RegionInfo.RegionID, scene);
+ }
+ }
+
+ void IRegionModuleBase.RemoveRegion(Scene scene)
+ {
+ if (!Enabled)
+ return;
+
+ lock (regions)
+ {
+ if (regions.ContainsKey(scene.RegionInfo.RegionID))
+ regions.Remove(scene.RegionInfo.RegionID);
+ }
+ }
+
+ void IRegionModuleBase.RegionLoaded(Scene scene)
+ {
+ if (!Enabled)
+ return;
+ }
+ #endregion
+ }
+}
\ 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
public LocalGridServicesConnector()
{
+ m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector no parms.");
}
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 @@
+using System;
+using System.Reflection;
+using Nini.Config;
+using OpenSim.Server.Base;
+using OpenSim.Services.Interfaces;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Framework;
+using OpenSim.Server.Handlers.Base;
+using log4net;
+
+namespace OpenSim.Server.Handlers.Profiles
+{
+ public class UserProfilesConnector: ServiceConnector
+ {
+ static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+
+ // Our Local Module
+ public IUserProfilesService ServiceModule
+ {
+ get; private set;
+ }
+
+ // The HTTP server.
+ public IHttpServer Server
+ {
+ get; private set;
+ }
+
+ public string ConfigName
+ {
+ get; private set;
+ }
+
+ public bool Enabled
+ {
+ get; private set;
+ }
+
+ public UserProfilesConnector(IConfigSource config, IHttpServer server, string configName) :
+ base(config, server, configName)
+ {
+ ConfigName = "UserProfilesService";
+ if(!string.IsNullOrEmpty(configName))
+ ConfigName = configName;
+
+ IConfig serverConfig = config.Configs[ConfigName];
+ if (serverConfig == null)
+ throw new Exception(String.Format("No section {0} in config file", ConfigName));
+
+ if(!serverConfig.GetBoolean("Enabled",false))
+ {
+ Enabled = false;
+ return;
+ }
+
+ Enabled = true;
+
+ Server = server;
+
+ string service = serverConfig.GetString("LocalServiceModule", String.Empty);
+
+ Object[] args = new Object[] { config, ConfigName };
+ ServiceModule = ServerUtils.LoadPlugin(service, args);
+
+ JsonRpcProfileHandlers handler = new JsonRpcProfileHandlers(ServiceModule);
+
+ Server.AddJsonRPCHandler("avatarclassifiedsrequest", handler.AvatarClassifiedsRequest);
+ Server.AddJsonRPCHandler("classified_update", handler.ClassifiedUpdate);
+ Server.AddJsonRPCHandler("classifieds_info_query", handler.ClassifiedInfoRequest);
+ Server.AddJsonRPCHandler("classified_delete", handler.ClassifiedDelete);
+ Server.AddJsonRPCHandler("avatarpicksrequest", handler.AvatarPicksRequest);
+ Server.AddJsonRPCHandler("pickinforequest", handler.PickInfoRequest);
+ Server.AddJsonRPCHandler("picks_update", handler.PicksUpdate);
+ Server.AddJsonRPCHandler("picks_delete", handler.PicksDelete);
+ Server.AddJsonRPCHandler("avatarnotesrequest", handler.AvatarNotesRequest);
+ Server.AddJsonRPCHandler("avatar_notes_update", handler.NotesUpdate);
+ Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest);
+ Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate);
+ Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate);
+ Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest);
+// Server.AddJsonRPCHandler("user_preferences_request", handler.UserPreferencesRequest);
+// Server.AddJsonRPCHandler("user_preferences_update", handler.UserPreferencesUpdate);
+// Server.AddJsonRPCHandler("user_account_create", handler.UserAccountCreate);
+// Server.AddJsonRPCHandler("user_account_auth", handler.UserAccountAuth);
+// Server.AddJsonRPCHandler("user_account_test", handler.UserAccountTest);
+ Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData);
+ Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData);
+ }
+ }
+}
+
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 @@
+using System;
+using System.Reflection;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using log4net;
+using OpenSim.Services.Interfaces;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Framework;
+
+namespace OpenSim.Server.Handlers
+{
+ public class UserProfilesHandlers
+ {
+ public UserProfilesHandlers ()
+ {
+ }
+ }
+
+ public class JsonRpcProfileHandlers
+ {
+ static readonly ILog m_log =
+ LogManager.GetLogger(
+ MethodBase.GetCurrentMethod().DeclaringType);
+
+ public IUserProfilesService Service
+ {
+ get; private set;
+ }
+
+ public JsonRpcProfileHandlers(IUserProfilesService service)
+ {
+ Service = service;
+ }
+
+ #region Classifieds
+ ///
+ /// Request avatar's classified ads.
+ ///
+ ///
+ /// An array containing all the calassified uuid and it's name created by the creator id
+ ///
+ ///
+ /// Our parameters are in the OSDMap json["params"]
+ ///
+ ///
+ /// If set to true response.
+ ///
+ public bool AvatarClassifiedsRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ m_log.DebugFormat ("Classified Request");
+ return false;
+ }
+
+ OSDMap request = (OSDMap)json["params"];
+ UUID creatorId = new UUID(request["creatorId"].AsString());
+
+
+ OSDArray data = (OSDArray) Service.AvatarClassifiedsRequest(creatorId);
+ response.Result = data;
+
+ return true;
+ }
+
+ public bool ClassifiedUpdate(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "Error parsing classified update request";
+ m_log.DebugFormat ("Classified Update Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserClassifiedAdd ad = new UserClassifiedAdd();
+ object Ad = (object)ad;
+ OSD.DeserializeMembers(ref Ad, (OSDMap)json["params"]);
+ if(Service.ClassifiedUpdate(ad, ref result))
+ {
+ response.Result = OSD.SerializeMembers(ad);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+
+ public bool ClassifiedDelete(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ m_log.DebugFormat ("Classified Delete Request");
+ return false;
+ }
+
+ OSDMap request = (OSDMap)json["params"];
+ UUID classifiedId = new UUID(request["classifiedID"].AsString());
+
+ OSDMap res = new OSDMap();
+ res["result"] = OSD.FromString("success");
+ response.Result = res;
+
+ return true;
+
+ }
+
+ public bool ClassifiedInfoRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("Classified Info Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserClassifiedAdd ad = new UserClassifiedAdd();
+ object Ad = (object)ad;
+ OSD.DeserializeMembers(ref Ad, (OSDMap)json["params"]);
+ if(Service.ClassifiedInfoRequest(ref ad, ref result))
+ {
+ response.Result = OSD.SerializeMembers(ad);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+ #endregion Classifieds
+
+ #region Picks
+ public bool AvatarPicksRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ m_log.DebugFormat ("Avatar Picks Request");
+ return false;
+ }
+
+ OSDMap request = (OSDMap)json["params"];
+ UUID creatorId = new UUID(request["creatorId"].AsString());
+
+
+ OSDArray data = (OSDArray) Service.AvatarPicksRequest(creatorId);
+ response.Result = data;
+
+ return true;
+ }
+
+ public bool PickInfoRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("Avatar Picks Info Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfilePick pick = new UserProfilePick();
+ object Pick = (object)pick;
+ OSD.DeserializeMembers(ref Pick, (OSDMap)json["params"]);
+ if(Service.PickInfoRequest(ref pick, ref result))
+ {
+ response.Result = OSD.SerializeMembers(pick);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+
+ public bool PicksUpdate(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("Avatar Picks Update Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfilePick pick = new UserProfilePick();
+ object Pick = (object)pick;
+ OSD.DeserializeMembers(ref Pick, (OSDMap)json["params"]);
+ if(Service.PicksUpdate(ref pick, ref result))
+ {
+ response.Result = OSD.SerializeMembers(pick);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = "unable to update pick";
+
+ return false;
+ }
+
+ public bool PicksDelete(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ m_log.DebugFormat ("Avatar Picks Delete Request");
+ return false;
+ }
+
+ OSDMap request = (OSDMap)json["params"];
+ UUID pickId = new UUID(request["pickId"].AsString());
+ if(Service.PicksDelete(pickId))
+ return true;
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = "data error removing record";
+ return false;
+ }
+ #endregion Picks
+
+ #region Notes
+ public bool AvatarNotesRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "Params missing";
+ m_log.DebugFormat ("Avatar Notes Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfileNotes note = new UserProfileNotes();
+ object Note = (object)note;
+ OSD.DeserializeMembers(ref Note, (OSDMap)json["params"]);
+ if(Service.AvatarNotesRequest(ref note))
+ {
+ response.Result = OSD.SerializeMembers(note);
+ return true;
+ }
+
+ object Notes = (object) note;
+ OSD.DeserializeMembers(ref Notes, (OSDMap)json["params"]);
+ return true;
+ }
+
+ public bool NotesUpdate(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "No parameters";
+ m_log.DebugFormat ("Avatar Notes Update Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfileNotes note = new UserProfileNotes();
+ object Notes = (object) note;
+ OSD.DeserializeMembers(ref Notes, (OSDMap)json["params"]);
+ if(Service.NotesUpdate(ref note, ref result))
+ {
+ response.Result = OSD.SerializeMembers(note);
+ return true;
+ }
+ return true;
+ }
+ #endregion Notes
+
+ #region Profile Properties
+ public bool AvatarPropertiesRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("Avatar Properties Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfileProperties props = new UserProfileProperties();
+ object Props = (object)props;
+ OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
+ if(Service.AvatarPropertiesRequest(ref props, ref result))
+ {
+ response.Result = OSD.SerializeMembers(props);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+
+ public bool AvatarPropertiesUpdate(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("Avatar Properties Update Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfileProperties props = new UserProfileProperties();
+ object Props = (object)props;
+ OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
+ if(Service.AvatarPropertiesUpdate(ref props, ref result))
+ {
+ response.Result = OSD.SerializeMembers(props);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+ #endregion Profile Properties
+
+ #region Interests
+ public bool AvatarInterestsUpdate(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("Avatar Interests Update Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserProfileProperties props = new UserProfileProperties();
+ object Props = (object)props;
+ OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
+ if(Service.AvatarInterestsUpdate(props, ref result))
+ {
+ response.Result = OSD.SerializeMembers(props);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+ #endregion Interests
+
+ #region Utility
+ public bool AvatarImageAssetsRequest(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ m_log.DebugFormat ("Avatar Image Assets Request");
+ return false;
+ }
+
+ OSDMap request = (OSDMap)json["params"];
+ UUID avatarId = new UUID(request["avatarId"].AsString());
+
+ OSDArray data = (OSDArray) Service.AvatarImageAssetsRequest(avatarId);
+ response.Result = data;
+
+ return true;
+ }
+ #endregion Utiltiy
+
+ #region UserData
+ public bool RequestUserAppData(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("User Application Service URL Request: No Parameters!");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserAppData props = new UserAppData();
+ object Props = (object)props;
+ OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
+ if(Service.RequestUserAppData(ref props, ref result))
+ {
+ OSDMap res = new OSDMap();
+ res["result"] = OSD.FromString("success");
+ res["token"] = OSD.FromString (result);
+ response.Result = res;
+
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+
+ public bool UpdateUserAppData(OSDMap json, ref JsonRpcResponse response)
+ {
+ if(!json.ContainsKey("params"))
+ {
+ response.Error.Code = ErrorCode.ParseError;
+ response.Error.Message = "no parameters supplied";
+ m_log.DebugFormat ("User App Data Update Request");
+ return false;
+ }
+
+ string result = string.Empty;
+ UserAppData props = new UserAppData();
+ object Props = (object)props;
+ OSD.DeserializeMembers(ref Props, (OSDMap)json["params"]);
+ if(Service.SetUserAppData(props, ref result))
+ {
+ response.Result = OSD.SerializeMembers(props);
+ return true;
+ }
+
+ response.Error.Code = ErrorCode.InternalError;
+ response.Error.Message = string.Format("{0}", result);
+ return false;
+ }
+ #endregion UserData
+ }
+}
+
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 @@
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+
+namespace OpenSim.Services.Interfaces
+{
+ public interface IUserProfilesService
+ {
+ #region Classifieds
+ OSD AvatarClassifiedsRequest(UUID creatorId);
+ bool ClassifiedUpdate(UserClassifiedAdd ad, ref string result);
+ bool ClassifiedInfoRequest(ref UserClassifiedAdd ad, ref string result);
+ bool ClassifiedDelete(UUID recordId);
+ #endregion Classifieds
+
+ #region Picks
+ OSD AvatarPicksRequest(UUID creatorId);
+ bool PickInfoRequest(ref UserProfilePick pick, ref string result);
+ bool PicksUpdate(ref UserProfilePick pick, ref string result);
+ bool PicksDelete(UUID pickId);
+ #endregion Picks
+
+ #region Notes
+ bool AvatarNotesRequest(ref UserProfileNotes note);
+ bool NotesUpdate(ref UserProfileNotes note, ref string result);
+ #endregion Notes
+
+ #region Profile Properties
+ bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result);
+ bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result);
+ #endregion Profile Properties
+
+ #region Interests
+ bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result);
+ #endregion Interests
+
+ #region Utility
+ OSD AvatarImageAssetsRequest(UUID avatarId);
+ #endregion Utility
+
+ #region UserData
+ bool RequestUserAppData(ref UserAppData prop, ref string result);
+ bool SetUserAppData(UserAppData prop, ref string result);
+ #endregion UserData
+ }
+}
+
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 @@
+using System;
+using System.Reflection;
+using System.Text;
+using Nini.Config;
+using log4net;
+using OpenSim.Server.Base;
+using OpenSim.Services.Interfaces;
+using OpenSim.Services.UserAccountService;
+using OpenSim.Data;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework;
+
+namespace OpenSim.Services.ProfilesService
+{
+ public class UserProfilesService: UserProfilesServiceBase, IUserProfilesService
+ {
+ static readonly ILog m_log =
+ LogManager.GetLogger(
+ MethodBase.GetCurrentMethod().DeclaringType);
+
+ IUserAccountService userAccounts;
+ IAuthenticationService authService;
+
+ public UserProfilesService(IConfigSource config, string configName):
+ base(config, configName)
+ {
+ IConfig Config = config.Configs[configName];
+ if (Config == null)
+ {
+ m_log.Warn("[PROFILES]: No configuration found!");
+ return;
+ }
+ Object[] args = null;
+
+ args = new Object[] { config };
+ string accountService = Config.GetString("UserAccountService", String.Empty);
+ if (accountService != string.Empty)
+ userAccounts = ServerUtils.LoadPlugin(accountService, args);
+
+ args = new Object[] { config };
+ string authServiceConfig = Config.GetString("AuthenticationServiceModule", String.Empty);
+ if (accountService != string.Empty)
+ authService = ServerUtils.LoadPlugin(authServiceConfig, args);
+ }
+
+ #region Classifieds
+ public OSD AvatarClassifiedsRequest(UUID creatorId)
+ {
+ OSDArray records = ProfilesData.GetClassifiedRecords(creatorId);
+
+ return records;
+ }
+
+ public bool ClassifiedUpdate(UserClassifiedAdd ad, ref string result)
+ {
+ if(!ProfilesData.UpdateClassifiedRecord(ad, ref result))
+ {
+ return false;
+ }
+ result = "success";
+ return true;
+ }
+
+ public bool ClassifiedDelete(UUID recordId)
+ {
+ if(ProfilesData.DeleteClassifiedRecord(recordId))
+ return true;
+
+ return false;
+ }
+
+ public bool ClassifiedInfoRequest(ref UserClassifiedAdd ad, ref string result)
+ {
+ if(ProfilesData.GetClassifiedInfo(ref ad, ref result))
+ return true;
+
+ return false;
+ }
+ #endregion Classifieds
+
+ #region Picks
+ public OSD AvatarPicksRequest(UUID creatorId)
+ {
+ OSDArray records = ProfilesData.GetAvatarPicks(creatorId);
+
+ return records;
+ }
+
+ public bool PickInfoRequest(ref UserProfilePick pick, ref string result)
+ {
+ pick = ProfilesData.GetPickInfo(pick.CreatorId, pick.PickId);
+ result = "OK";
+ return true;
+ }
+
+ public bool PicksUpdate(ref UserProfilePick pick, ref string result)
+ {
+ return ProfilesData.UpdatePicksRecord(pick);
+ }
+
+ public bool PicksDelete(UUID pickId)
+ {
+ return ProfilesData.DeletePicksRecord(pickId);
+ }
+ #endregion Picks
+
+ #region Notes
+ public bool AvatarNotesRequest(ref UserProfileNotes note)
+ {
+ return ProfilesData.GetAvatarNotes(ref note);
+ }
+
+ public bool NotesUpdate(ref UserProfileNotes note, ref string result)
+ {
+ return ProfilesData.UpdateAvatarNotes(ref note, ref result);
+ }
+ #endregion Notes
+
+ #region Profile Properties
+ public bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result)
+ {
+ return ProfilesData.GetAvatarProperties(ref prop, ref result);
+ }
+
+ public bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result)
+ {
+ return ProfilesData.UpdateAvatarProperties(ref prop, ref result);
+ }
+ #endregion Profile Properties
+
+ #region Interests
+ public bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result)
+ {
+ return ProfilesData.UpdateAvatarInterests(prop, ref result);
+ }
+ #endregion Interests
+
+ #region Utility
+ public OSD AvatarImageAssetsRequest(UUID avatarId)
+ {
+ OSDArray records = ProfilesData.GetUserImageAssets(avatarId);
+ return records;
+ }
+ #endregion Utility
+
+ #region UserData
+ public bool RequestUserAppData(ref UserAppData prop, ref string result)
+ {
+ return ProfilesData.GetUserAppData(ref prop, ref result);
+ }
+
+ public bool SetUserAppData(UserAppData prop, ref string result)
+ {
+ return true;
+ }
+ #endregion UserData
+ }
+}
+
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 @@
+using System;
+using System.Reflection;
+using Nini.Config;
+using log4net;
+using OpenSim.Services.Base;
+using OpenSim.Data;
+
+namespace OpenSim.Services.ProfilesService
+{
+ public class UserProfilesServiceBase: ServiceBase
+ {
+ static readonly ILog m_log =
+ LogManager.GetLogger(
+ MethodBase.GetCurrentMethod().DeclaringType);
+
+ public IProfilesData ProfilesData;
+
+ public string ConfigName
+ {
+ get; private set;
+ }
+
+ public UserProfilesServiceBase(IConfigSource config, string configName):
+ base(config)
+ {
+ if(string.IsNullOrEmpty(configName))
+ {
+ m_log.WarnFormat("[PROFILES]: Configuration section not given!");
+ return;
+ }
+
+ string dllName = String.Empty;
+ string connString = null;
+ string realm = String.Empty;
+
+ IConfig dbConfig = config.Configs["DatabaseService"];
+ if (dbConfig != null)
+ {
+ if (dllName == String.Empty)
+ dllName = dbConfig.GetString("StorageProvider", String.Empty);
+ if (string.IsNullOrEmpty(connString))
+ connString = dbConfig.GetString("ConnectionString", String.Empty);
+ }
+
+ IConfig ProfilesConfig = config.Configs[configName];
+ if (ProfilesConfig != null)
+ {
+ connString = ProfilesConfig.GetString("ConnectionString", connString);
+ realm = ProfilesConfig.GetString("Realm", realm);
+ }
+
+ ProfilesData = LoadPlugin(dllName, new Object[] { connString });
+ if (ProfilesData == null)
+ throw new Exception("Could not find a storage interface in the given module");
+
+ }
+ }
+}
+
--
cgit v1.1
From 46335b103e1f993c6aa77e46f89e5ee0d6d7497e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 30 May 2013 23:51:35 +0100
Subject: If an exception occurs in the AsyncCommandManager loop, spit it out
to log rather than silently swallowing it.
This might help diagnose the cause of http://opensimulator.org/mantis/view.php?id=6651 where sometimes scripts fail to start on region start.
---
.../Shared/Api/Implementation/AsyncCommandManager.cs | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 1c59624..352e316 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public class AsyncCommandManager
{
-// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Thread cmdHandlerThread;
private static int cmdHandlerThreadCycleSleepms;
@@ -183,17 +183,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
try
{
- while (true)
- {
- Thread.Sleep(cmdHandlerThreadCycleSleepms);
+ Thread.Sleep(cmdHandlerThreadCycleSleepms);
- DoOneCmdHandlerPass();
+ DoOneCmdHandlerPass();
- Watchdog.UpdateThread();
- }
+ Watchdog.UpdateThread();
}
- catch
+ catch (Exception e)
{
+ m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e);
}
}
}
--
cgit v1.1
From 439f11cc3cf2ab8f7fdc1d8746f1d8ab44c911eb Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 30 May 2013 09:21:58 -0700
Subject: Add region heartbeat start event to complement heartbeat end event.
This allows object modification before the usual heartbeat operation.
---
OpenSim/Region/Framework/Scenes/EventManager.cs | 23 +++++++++++++++++++++++
OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++
2 files changed, 25 insertions(+)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 59d0148..a246319 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -969,6 +969,8 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void RegionStarted(Scene scene);
public event RegionStarted OnRegionStarted;
+ public delegate void RegionHeartbeatStart(Scene scene);
+ public event RegionHeartbeatStart OnRegionHeartbeatStart;
public delegate void RegionHeartbeatEnd(Scene scene);
public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
@@ -3068,6 +3070,27 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public void TriggerRegionHeartbeatStart(Scene scene)
+ {
+ RegionHeartbeatStart handler = OnRegionHeartbeatStart;
+
+ if (handler != null)
+ {
+ foreach (RegionHeartbeatStart d in handler.GetInvocationList())
+ {
+ try
+ {
+ d(scene);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("[EVENT MANAGER]: Delegate for OnRegionHeartbeatStart failed - continuing {0} - {1}",
+ e.Message, e.StackTrace);
+ }
+ }
+ }
+ }
+
public void TriggerRegionHeartbeatEnd(Scene scene)
{
RegionHeartbeatEnd handler = OnRegionHeartbeatEnd;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 5dea634..0743ce7 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1517,6 +1517,8 @@ namespace OpenSim.Region.Framework.Scenes
try
{
+ EventManager.TriggerRegionHeartbeatStart(this);
+
// Apply taints in terrain module to terrain in physics scene
if (Frame % m_update_terrain == 0)
{
--
cgit v1.1
From 48a175eff760e04f8096acd404058755d7c2919c Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 30 May 2013 14:30:45 -0700
Subject: Add methods to Animation and AnimationSet for easier manipulation and
display of groups of animations (Equal(), ToString(), FromOSDArray(), ...).
No functional change to animations.
---
OpenSim/Framework/Animation.cs | 20 ++++
.../Framework/Scenes/Animation/AnimationSet.cs | 110 +++++++++++++++++++++
.../Scenes/Animation/DefaultAvatarAnimations.cs | 26 +++++
3 files changed, 156 insertions(+)
(limited to 'OpenSim')
diff --git a/OpenSim/Framework/Animation.cs b/OpenSim/Framework/Animation.cs
index 232f5a1..8bdf8f4 100644
--- a/OpenSim/Framework/Animation.cs
+++ b/OpenSim/Framework/Animation.cs
@@ -120,5 +120,25 @@ namespace OpenSim.Framework
sequenceNum = args["seq_num"].AsInteger();
}
+ public override bool Equals(object obj)
+ {
+ Animation other = obj as Animation;
+ if (other != null)
+ {
+ return (other.AnimID == this.AnimID
+ && other.SequenceNum == this.SequenceNum
+ && other.ObjectID == this.ObjectID);
+ }
+
+ return base.Equals(obj);
+ }
+
+ public override string ToString()
+ {
+ return "AnimID=" + AnimID.ToString()
+ + "/seq=" + SequenceNum.ToString()
+ + "/objID=" + ObjectID.ToString();
+ }
+
}
}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index 66edfed..5dee64d 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -28,8 +28,11 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using System.Text;
using log4net;
using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+
using OpenSim.Framework;
using Animation = OpenSim.Framework.Animation;
@@ -60,6 +63,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
ResetDefaultAnimation();
}
+ public AnimationSet(OSDArray pArray)
+ {
+ ResetDefaultAnimation();
+ FromOSDArray(pArray);
+ }
+
public bool HasAnimation(UUID animID)
{
if (m_defaultAnimation.AnimID == animID)
@@ -218,5 +227,106 @@ namespace OpenSim.Region.Framework.Scenes.Animation
foreach (OpenSim.Framework.Animation anim in theArray)
m_animations.Add(anim);
}
+
+ // Create representation of this AnimationSet as an OSDArray.
+ // First two entries in the array are the default and implicitDefault animations
+ // followed by the other animations.
+ public OSDArray ToOSDArray()
+ {
+ OSDArray ret = new OSDArray();
+ ret.Add(DefaultAnimation.PackUpdateMessage());
+ ret.Add(ImplicitDefaultAnimation.PackUpdateMessage());
+
+ foreach (OpenSim.Framework.Animation anim in m_animations)
+ ret.Add(anim.PackUpdateMessage());
+
+ return ret;
+ }
+
+ public void FromOSDArray(OSDArray pArray)
+ {
+ this.Clear();
+
+ if (pArray.Count >= 1)
+ {
+ m_defaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[0]);
+ }
+ if (pArray.Count >= 2)
+ {
+ m_implicitDefaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[1]);
+ }
+ for (int ii = 2; ii < pArray.Count; ii++)
+ {
+ m_animations.Add(new OpenSim.Framework.Animation((OSDMap)pArray[ii]));
+ }
+ }
+
+ // Compare two AnimationSets and return 'true' if the default animations are the same
+ // and all of the animations in the list are equal.
+ public override bool Equals(object obj)
+ {
+ AnimationSet other = obj as AnimationSet;
+ if (other != null)
+ {
+ if (this.DefaultAnimation.Equals(other.DefaultAnimation)
+ && this.ImplicitDefaultAnimation.Equals(other.ImplicitDefaultAnimation))
+ {
+ // The defaults are the same. Is the list of animations the same?
+ OpenSim.Framework.Animation[] thisAnims = this.ToArray();
+ OpenSim.Framework.Animation[] otherAnims = other.ToArray();
+ if (thisAnims.Length == 0 && otherAnims.Length == 0)
+ return true; // the common case
+ if (thisAnims.Length == otherAnims.Length)
+ {
+ // Do this the hard way but since the list is usually short this won't take long.
+ foreach (OpenSim.Framework.Animation thisAnim in thisAnims)
+ {
+ bool found = false;
+ foreach (OpenSim.Framework.Animation otherAnim in otherAnims)
+ {
+ if (thisAnim.Equals(otherAnim))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ // If anything is not in the other list, these are not equal
+ return false;
+ }
+ }
+ // Found everything in the other list. Since lists are equal length, they must be equal.
+ return true;
+ }
+ }
+ return false;
+ }
+ // Don't know what was passed, but the base system will figure it out for me.
+ return base.Equals(obj);
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buff = new StringBuilder();
+ buff.Append("dflt=");
+ buff.Append(DefaultAnimation.ToString());
+ buff.Append(",iDflt=");
+ if (DefaultAnimation == ImplicitDefaultAnimation)
+ buff.Append("same");
+ else
+ buff.Append(ImplicitDefaultAnimation.ToString());
+ if (m_animations.Count > 0)
+ {
+ buff.Append(",anims=");
+ foreach (OpenSim.Framework.Animation anim in m_animations)
+ {
+ buff.Append("<");
+ buff.Append(anim.ToString());
+ buff.Append(">,");
+ }
+ }
+ return buff.ToString();
+ }
}
}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
index c2b0468..b79dd8f 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
@@ -104,5 +104,31 @@ namespace OpenSim.Region.Framework.Scenes.Animation
return UUID.Zero;
}
+
+ ///
+ /// Get the name of the animation given a UUID. If there is no matching animation
+ /// return the UUID as a string.
+ ///
+ public static string GetDefaultAnimationName(UUID uuid)
+ {
+ string ret = "unknown";
+ if (AnimsUUID.ContainsValue(uuid))
+ {
+ foreach (KeyValuePair kvp in AnimsUUID)
+ {
+ if (kvp.Value == uuid)
+ {
+ ret = kvp.Key;
+ break;
+ }
+ }
+ }
+ else
+ {
+ ret = uuid.ToString();
+ }
+
+ return ret;
+ }
}
}
\ No newline at end of file
--
cgit v1.1
From 4d32ca19bf27048105aeb01c67f0f9647ed3e700 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Thu, 30 May 2013 19:15:14 -0700
Subject: Trigger OnScenePresenceUpdated when the avatar's animations change.
---
.../Framework/Scenes/Animation/ScenePresenceAnimator.cs | 17 ++++++++++++++---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 +++++++-
2 files changed, 21 insertions(+), 4 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index e92a087..a701a79 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -92,7 +92,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
GetAnimName(animID), animID, m_scenePresence.Name);
if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
+ {
SendAnimPack();
+ }
}
// Called from scripts
@@ -131,7 +133,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
GetAnimName(animID), animID, m_scenePresence.Name);
if (m_animations.Remove(animID, allowNoDefault))
+ {
SendAnimPack();
+ }
}
// Called from scripts
@@ -163,8 +167,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// The movement animation is reserved for "main" animations
/// that are mutually exclusive, e.g. flying and sitting.
///
- public void TrySetMovementAnimation(string anim)
+ /// 'true' if the animation was updated
+ public bool TrySetMovementAnimation(string anim)
{
+ bool ret = false;
if (!m_scenePresence.IsChildAgent)
{
// m_log.DebugFormat(
@@ -181,6 +187,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
// 16384 is CHANGED_ANIMATION
m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION});
SendAnimPack();
+ ret = true;
}
}
else
@@ -189,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
"[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}",
anim, m_scenePresence.Name);
}
+ return ret;
}
///
@@ -422,8 +430,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
///
/// Update the movement animation of this avatar according to its current state
///
- public void UpdateMovementAnimations()
+ /// 'true' if the animation was changed
+ public bool UpdateMovementAnimations()
{
+ bool ret = false;
lock (m_animations)
{
string newMovementAnimation = DetermineMovementAnimation();
@@ -437,9 +447,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
// Only set it if it's actually changed, give a script
// a chance to stop a default animation
- TrySetMovementAnimation(CurrentMovementAnimation);
+ ret = TrySetMovementAnimation(CurrentMovementAnimation);
}
}
+ return ret;
}
public UUID[] GetAnimationArray()
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e8aa52e..b8ff7f7 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2039,6 +2039,7 @@ namespace OpenSim.Region.Framework.Scenes
}
Animator.TrySetMovementAnimation("STAND");
+ TriggerScenePresenceUpdated();
}
private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -2432,6 +2433,7 @@ namespace OpenSim.Region.Framework.Scenes
}
Animator.TrySetMovementAnimation(sitAnimation);
SendAvatarDataToAllAgents();
+ TriggerScenePresenceUpdated();
}
}
@@ -2440,6 +2442,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick..
m_AngularVelocity = Vector3.Zero;
Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
+ TriggerScenePresenceUpdated();
SitGround = true;
RemoveFromPhysicalScene();
}
@@ -2456,11 +2459,13 @@ namespace OpenSim.Region.Framework.Scenes
public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
{
Animator.AddAnimation(animID, UUID.Zero);
+ TriggerScenePresenceUpdated();
}
public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
{
Animator.RemoveAnimation(animID, false);
+ TriggerScenePresenceUpdated();
}
///
@@ -3465,7 +3470,8 @@ namespace OpenSim.Region.Framework.Scenes
// if (m_updateCount > 0)
// {
- Animator.UpdateMovementAnimations();
+ if (Animator.UpdateMovementAnimations())
+ TriggerScenePresenceUpdated();
// m_updateCount--;
// }
--
cgit v1.1
From bf035233232885b798a56a1687319ba167e4bf60 Mon Sep 17 00:00:00 2001
From: BlueWall
Date: Fri, 31 May 2013 10:40:47 -0400
Subject: Fill in fields with default values on profile creation
---
OpenSim/Data/MySQL/MySQLUserProfilesData.cs | 50 +++++++++++++++++++++++++++--
1 file changed, 48 insertions(+), 2 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
index 09bd448..5d7149b 100644
--- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
+++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs
@@ -622,7 +622,7 @@ namespace OpenSim.Data.MySQL
{
m_log.DebugFormat("[PROFILES_DATA]" +
": No data for {0}", props.UserId);
-
+
props.WebUrl = string.Empty;
props.ImageId = UUID.Zero;
props.AboutText = string.Empty;
@@ -634,8 +634,38 @@ namespace OpenSim.Data.MySQL
props.SkillsMask = 0;
props.SkillsText = string.Empty;
props.Language = string.Empty;
+ props.PublishProfile = false;
+ props.PublishMature = false;
- query = "INSERT INTO userprofile (`useruuid`) VALUES (?userId)";
+ query = "INSERT INTO userprofile (";
+ query += "useruuid, ";
+ query += "profilePartner, ";
+ query += "profileAllowPublish, ";
+ query += "profileMaturePublish, ";
+ query += "profileURL, ";
+ query += "profileWantToMask, ";
+ query += "profileWantToText, ";
+ query += "profileSkillsMask, ";
+ query += "profileSkillsText, ";
+ query += "profileLanguages, ";
+ query += "profileImage, ";
+ query += "profileAboutText, ";
+ query += "profileFirstImage, ";
+ query += "profileFirstText) VALUES (";
+ query += "?userId, ";
+ query += "?profilePartner, ";
+ query += "?profileAllowPublish, ";
+ query += "?profileMaturePublish, ";
+ query += "?profileURL, ";
+ query += "?profileWantToMask, ";
+ query += "?profileWantToText, ";
+ query += "?profileSkillsMask, ";
+ query += "?profileSkillsText, ";
+ query += "?profileLanguages, ";
+ query += "?profileImage, ";
+ query += "?profileAboutText, ";
+ query += "?profileFirstImage, ";
+ query += "?profileFirstText)";
dbcon.Close();
dbcon.Open();
@@ -643,6 +673,20 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand put = new MySqlCommand(query, dbcon))
{
put.Parameters.AddWithValue("?userId", props.UserId.ToString());
+ put.Parameters.AddWithValue("?profilePartner", props.PartnerId.ToString());
+ put.Parameters.AddWithValue("?profileAllowPublish", props.PublishProfile);
+ put.Parameters.AddWithValue("?profileMaturePublish", props.PublishMature);
+ put.Parameters.AddWithValue("?profileURL", props.WebUrl);
+ put.Parameters.AddWithValue("?profileWantToMask", props.WantToMask);
+ put.Parameters.AddWithValue("?profileWantToText", props.WantToText);
+ put.Parameters.AddWithValue("?profileSkillsMask", props.SkillsMask);
+ put.Parameters.AddWithValue("?profileSkillsText", props.SkillsText);
+ put.Parameters.AddWithValue("?profileLanguages", props.Language);
+ put.Parameters.AddWithValue("?profileImage", props.ImageId.ToString());
+ put.Parameters.AddWithValue("?profileAboutText", props.AboutText);
+ put.Parameters.AddWithValue("?profileFirstImage", props.FirstLifeImageId.ToString());
+ put.Parameters.AddWithValue("?profileFirstText", props.FirstLifeText);
+
put.ExecuteNonQuery();
}
}
@@ -665,6 +709,7 @@ namespace OpenSim.Data.MySQL
string query = string.Empty;
query += "UPDATE userprofile SET ";
+ query += "profilePartner=?profilePartner, ";
query += "profileURL=?profileURL, ";
query += "profileImage=?image, ";
query += "profileAboutText=?abouttext,";
@@ -680,6 +725,7 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
{
cmd.Parameters.AddWithValue("?profileURL", props.WebUrl);
+ cmd.Parameters.AddWithValue("?profilePartner", props.PartnerId.ToString());
cmd.Parameters.AddWithValue("?image", props.ImageId.ToString());
cmd.Parameters.AddWithValue("?abouttext", props.AboutText);
cmd.Parameters.AddWithValue("?firstlifeimage", props.FirstLifeImageId.ToString());
--
cgit v1.1
From 00c1586ff8cd0abb2270a109087857adefe3b5c2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 31 May 2013 18:12:36 +0100
Subject: refactor: Remove unused AsyncCommandManager.PleaseShutdown
---
.../Shared/Api/Implementation/AsyncCommandManager.cs | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 352e316..c71b571 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -377,23 +377,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
}
-
- #region Check llRemoteData channels
-
- #endregion
-
- #region Check llListeners
-
- #endregion
-
- ///
- /// If set to true then threads and stuff should try to make a graceful exit
- ///
- public bool PleaseShutdown
- {
- get { return _PleaseShutdown; }
- set { _PleaseShutdown = value; }
- }
- private bool _PleaseShutdown = false;
}
-}
+}
\ No newline at end of file
--
cgit v1.1
From 921ad8704e08fccc994f7907e7cb1e9372e355b9 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 31 May 2013 22:50:15 +0100
Subject: Lock areas of AsyncCommandManager where multiple threads could try to
access/update the same static structures simultaneously.
This is possible where there is more than one scene (multiple copies of the same script engine) and/or more than one script engine being used.
These operations are not thread safe and could be leading to the exceptions/problems seen in http://opensimulator.org/mantis/view.php?id=6651
This also prevents a small race condition where more than one AsyncLSLCmdHandlerThread could be started.
---
.../Api/Implementation/AsyncCommandManager.cs | 288 +++++++++++++--------
1 file changed, 177 insertions(+), 111 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index c71b571..72e8415 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -52,6 +52,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
private static Thread cmdHandlerThread;
private static int cmdHandlerThreadCycleSleepms;
+ ///
+ /// Lock for reading/writing static components of AsyncCommandManager.
+ ///
+ ///
+ /// This lock exists so that multiple threads from different engines and/or different copies of the same engine
+ /// are prevented from running non-thread safe code (e.g. read/write of lists) concurrently.
+ ///
+ private static object staticLock = new object();
+
private static List m_Scenes = new List();
private static List m_ScriptEngines =
new List();
@@ -74,37 +83,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public Dataserver DataserverPlugin
{
- get { return m_Dataserver[m_ScriptEngine]; }
+ get
+ {
+ lock (staticLock)
+ return m_Dataserver[m_ScriptEngine];
+ }
}
public Timer TimerPlugin
{
- get { return m_Timer[m_ScriptEngine]; }
+ get
+ {
+ lock (staticLock)
+ return m_Timer[m_ScriptEngine];
+ }
}
public HttpRequest HttpRequestPlugin
{
- get { return m_HttpRequest[m_ScriptEngine]; }
+ get
+ {
+ lock (staticLock)
+ return m_HttpRequest[m_ScriptEngine];
+ }
}
public Listener ListenerPlugin
{
- get { return m_Listener[m_ScriptEngine]; }
+ get
+ {
+ lock (staticLock)
+ return m_Listener[m_ScriptEngine];
+ }
}
public SensorRepeat SensorRepeatPlugin
{
- get { return m_SensorRepeat[m_ScriptEngine]; }
+ get
+ {
+ lock (staticLock)
+ return m_SensorRepeat[m_ScriptEngine];
+ }
}
public XmlRequest XmlRequestPlugin
{
- get { return m_XmlRequest[m_ScriptEngine]; }
+ get
+ {
+ lock (staticLock)
+ return m_XmlRequest[m_ScriptEngine];
+ }
}
public IScriptEngine[] ScriptEngines
{
- get { return m_ScriptEngines.ToArray(); }
+ get
+ {
+ lock (staticLock)
+ return m_ScriptEngines.ToArray();
+ }
}
public AsyncCommandManager(IScriptEngine _ScriptEngine)
@@ -112,29 +149,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_ScriptEngine = _ScriptEngine;
m_Scene = m_ScriptEngine.World;
- if (m_Scenes.Count == 0)
- ReadConfig();
-
- if (!m_Scenes.Contains(m_Scene))
- m_Scenes.Add(m_Scene);
- if (!m_ScriptEngines.Contains(m_ScriptEngine))
- m_ScriptEngines.Add(m_ScriptEngine);
-
- // Create instances of all plugins
- if (!m_Dataserver.ContainsKey(m_ScriptEngine))
- m_Dataserver[m_ScriptEngine] = new Dataserver(this);
- if (!m_Timer.ContainsKey(m_ScriptEngine))
- m_Timer[m_ScriptEngine] = new Timer(this);
- if (!m_HttpRequest.ContainsKey(m_ScriptEngine))
- m_HttpRequest[m_ScriptEngine] = new HttpRequest(this);
- if (!m_Listener.ContainsKey(m_ScriptEngine))
- m_Listener[m_ScriptEngine] = new Listener(this);
- if (!m_SensorRepeat.ContainsKey(m_ScriptEngine))
- m_SensorRepeat[m_ScriptEngine] = new SensorRepeat(this);
- if (!m_XmlRequest.ContainsKey(m_ScriptEngine))
- m_XmlRequest[m_ScriptEngine] = new XmlRequest(this);
-
- StartThread();
+ // If there is more than one scene in the simulator or multiple script engines are used on the same region
+ // then more than one thread could arrive at this block of code simultaneously. However, it cannot be
+ // executed concurrently both because concurrent list operations are not thread-safe and because of other
+ // race conditions such as the later check of cmdHandlerThread == null.
+ lock (staticLock)
+ {
+ if (m_Scenes.Count == 0)
+ ReadConfig();
+
+ if (!m_Scenes.Contains(m_Scene))
+ m_Scenes.Add(m_Scene);
+ if (!m_ScriptEngines.Contains(m_ScriptEngine))
+ m_ScriptEngines.Add(m_ScriptEngine);
+
+ // Create instances of all plugins
+ if (!m_Dataserver.ContainsKey(m_ScriptEngine))
+ m_Dataserver[m_ScriptEngine] = new Dataserver(this);
+ if (!m_Timer.ContainsKey(m_ScriptEngine))
+ m_Timer[m_ScriptEngine] = new Timer(this);
+ if (!m_HttpRequest.ContainsKey(m_ScriptEngine))
+ m_HttpRequest[m_ScriptEngine] = new HttpRequest(this);
+ if (!m_Listener.ContainsKey(m_ScriptEngine))
+ m_Listener[m_ScriptEngine] = new Listener(this);
+ if (!m_SensorRepeat.ContainsKey(m_ScriptEngine))
+ m_SensorRepeat[m_ScriptEngine] = new SensorRepeat(this);
+ if (!m_XmlRequest.ContainsKey(m_ScriptEngine))
+ m_XmlRequest[m_ScriptEngine] = new XmlRequest(this);
+
+ StartThread();
+ }
}
private static void StartThread()
@@ -198,25 +242,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
private static void DoOneCmdHandlerPass()
{
- // Check HttpRequests
- m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests();
+ lock (staticLock)
+ {
+ // Check HttpRequests
+ m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests();
- // Check XMLRPCRequests
- m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests();
+ // Check XMLRPCRequests
+ m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests();
- foreach (IScriptEngine s in m_ScriptEngines)
- {
- // Check Listeners
- m_Listener[s].CheckListeners();
+ foreach (IScriptEngine s in m_ScriptEngines)
+ {
+ // Check Listeners
+ m_Listener[s].CheckListeners();
- // Check timers
- m_Timer[s].CheckTimerEvents();
+ // Check timers
+ m_Timer[s].CheckTimerEvents();
- // Check Sensors
- m_SensorRepeat[s].CheckSenseRepeaterEvents();
+ // Check Sensors
+ m_SensorRepeat[s].CheckSenseRepeaterEvents();
- // Check dataserver
- m_Dataserver[s].ExpireRequests();
+ // Check dataserver
+ m_Dataserver[s].ExpireRequests();
+ }
}
}
@@ -229,32 +276,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
- // Remove a specific script
+ lock (staticLock)
+ {
+ // Remove dataserver events
+ m_Dataserver[engine].RemoveEvents(localID, itemID);
- // Remove dataserver events
- m_Dataserver[engine].RemoveEvents(localID, itemID);
+ // Remove from: Timers
+ m_Timer[engine].UnSetTimerEvents(localID, itemID);
- // Remove from: Timers
- m_Timer[engine].UnSetTimerEvents(localID, itemID);
+ // Remove from: HttpRequest
+ IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface();
+ if (iHttpReq != null)
+ iHttpReq.StopHttpRequestsForScript(itemID);
- // Remove from: HttpRequest
- IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface();
- if (iHttpReq != null)
- iHttpReq.StopHttpRequestsForScript(itemID);
+ IWorldComm comms = engine.World.RequestModuleInterface();
+ if (comms != null)
+ comms.DeleteListener(itemID);
- IWorldComm comms = engine.World.RequestModuleInterface();
- if (comms != null)
- comms.DeleteListener(itemID);
+ IXMLRPC xmlrpc = engine.World.RequestModuleInterface();
+ if (xmlrpc != null)
+ {
+ xmlrpc.DeleteChannels(itemID);
+ xmlrpc.CancelSRDRequests(itemID);
+ }
- IXMLRPC xmlrpc = engine.World.RequestModuleInterface();
- if (xmlrpc != null)
- {
- xmlrpc.DeleteChannels(itemID);
- xmlrpc.CancelSRDRequests(itemID);
+ // Remove Sensors
+ m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
}
-
- // Remove Sensors
- m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
}
///
@@ -264,10 +312,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public static SensorRepeat GetSensorRepeatPlugin(IScriptEngine engine)
{
- if (m_SensorRepeat.ContainsKey(engine))
- return m_SensorRepeat[engine];
- else
- return null;
+ lock (staticLock)
+ {
+ if (m_SensorRepeat.ContainsKey(engine))
+ return m_SensorRepeat[engine];
+ else
+ return null;
+ }
}
///
@@ -277,10 +328,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public static Dataserver GetDataserverPlugin(IScriptEngine engine)
{
- if (m_Dataserver.ContainsKey(engine))
- return m_Dataserver[engine];
- else
- return null;
+ lock (staticLock)
+ {
+ if (m_Dataserver.ContainsKey(engine))
+ return m_Dataserver[engine];
+ else
+ return null;
+ }
}
///
@@ -290,10 +344,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public static Timer GetTimerPlugin(IScriptEngine engine)
{
- if (m_Timer.ContainsKey(engine))
- return m_Timer[engine];
- else
- return null;
+ lock (staticLock)
+ {
+ if (m_Timer.ContainsKey(engine))
+ return m_Timer[engine];
+ else
+ return null;
+ }
}
///
@@ -303,38 +360,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
public static Listener GetListenerPlugin(IScriptEngine engine)
{
- if (m_Listener.ContainsKey(engine))
- return m_Listener[engine];
- else
- return null;
+ lock (staticLock)
+ {
+ if (m_Listener.ContainsKey(engine))
+ return m_Listener[engine];
+ else
+ return null;
+ }
}
public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
{
List