diff options
54 files changed, 3029 insertions, 2017 deletions
diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs index 6fd3d30..1e85a22 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs | |||
@@ -102,8 +102,6 @@ namespace OpenSim.ApplicationPlugins.LoadRegions | |||
102 | m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); | 102 | m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); |
103 | m_log.Info("[LOADREGIONSPLUGIN]: DynamicTextureModule..."); | 103 | m_log.Info("[LOADREGIONSPLUGIN]: DynamicTextureModule..."); |
104 | m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); | 104 | m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); |
105 | m_log.Info("[LOADREGIONSPLUGIN]: InstantMessageModule..."); | ||
106 | m_openSim.ModuleLoader.LoadDefaultSharedModule(new InstantMessageModule()); | ||
107 | m_log.Info("[LOADREGIONSPLUGIN]: LoadImageURLModule..."); | 105 | m_log.Info("[LOADREGIONSPLUGIN]: LoadImageURLModule..."); |
108 | m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule()); | 106 | m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule()); |
109 | m_log.Info("[LOADREGIONSPLUGIN]: XMLRPCModule..."); | 107 | m_log.Info("[LOADREGIONSPLUGIN]: XMLRPCModule..."); |
@@ -217,4 +215,4 @@ namespace OpenSim.ApplicationPlugins.LoadRegions | |||
217 | } | 215 | } |
218 | } | 216 | } |
219 | } | 217 | } |
220 | } \ No newline at end of file | 218 | } |
diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs index 6c0c74d..2e883d6 100644 --- a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs +++ b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs | |||
@@ -65,9 +65,13 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController | |||
65 | 65 | ||
66 | public void Initialise (OpenSimBase openSim) | 66 | public void Initialise (OpenSimBase openSim) |
67 | { | 67 | { |
68 | m_log.DebugFormat("[REGIONMODULES]: Initializing..."); | ||
69 | m_openSim = openSim; | 68 | m_openSim = openSim; |
70 | openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this); | 69 | } |
70 | |||
71 | public void PostInitialise () | ||
72 | { | ||
73 | m_log.DebugFormat("[REGIONMODULES]: Initializing..."); | ||
74 | m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this); | ||
71 | 75 | ||
72 | // Who we are | 76 | // Who we are |
73 | string id = AddinManager.CurrentAddin.Id; | 77 | string id = AddinManager.CurrentAddin.Id; |
@@ -81,9 +85,9 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController | |||
81 | 85 | ||
82 | // The [Modules] section in the ini file | 86 | // The [Modules] section in the ini file |
83 | IConfig modulesConfig = | 87 | IConfig modulesConfig = |
84 | openSim.ConfigSource.Source.Configs["Modules"]; | 88 | m_openSim.ConfigSource.Source.Configs["Modules"]; |
85 | if (modulesConfig == null) | 89 | if (modulesConfig == null) |
86 | modulesConfig = openSim.ConfigSource.Source.AddConfig("Modules"); | 90 | modulesConfig = m_openSim.ConfigSource.Source.AddConfig("Modules"); |
87 | 91 | ||
88 | // Scan modules and load all that aren't disabled | 92 | // Scan modules and load all that aren't disabled |
89 | foreach (TypeExtensionNode node in | 93 | foreach (TypeExtensionNode node in |
@@ -195,7 +199,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController | |||
195 | 199 | ||
196 | // OK, we're up and running | 200 | // OK, we're up and running |
197 | m_sharedInstances.Add(module); | 201 | m_sharedInstances.Add(module); |
198 | module.Initialise(openSim.ConfigSource.Source); | 202 | module.Initialise(m_openSim.ConfigSource.Source); |
199 | } | 203 | } |
200 | 204 | ||
201 | // Immediately run PostInitialise on shared modules | 205 | // Immediately run PostInitialise on shared modules |
@@ -205,10 +209,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController | |||
205 | } | 209 | } |
206 | } | 210 | } |
207 | 211 | ||
208 | public void PostInitialise () | ||
209 | { | ||
210 | } | ||
211 | |||
212 | #endregion | 212 | #endregion |
213 | 213 | ||
214 | #region IPlugin implementation | 214 | #region IPlugin implementation |
diff --git a/OpenSim/Data/IPresenceData.cs b/OpenSim/Data/IPresenceData.cs index e5a8ebd..71d0e31 100644 --- a/OpenSim/Data/IPresenceData.cs +++ b/OpenSim/Data/IPresenceData.cs | |||
@@ -32,25 +32,28 @@ using OpenSim.Framework; | |||
32 | 32 | ||
33 | namespace OpenSim.Data | 33 | namespace OpenSim.Data |
34 | { | 34 | { |
35 | public struct PresenceData | 35 | // This MUST be a ref type! |
36 | public class PresenceData | ||
36 | { | 37 | { |
37 | public UUID UUID; | 38 | public string UserID; |
38 | public UUID currentRegion; | 39 | public UUID RegionID; |
40 | public UUID SessionID; | ||
39 | public Dictionary<string, string> Data; | 41 | public Dictionary<string, string> Data; |
40 | } | 42 | } |
41 | 43 | ||
42 | /// <summary> | 44 | /// <summary> |
43 | /// An interface for connecting to the authentication datastore | 45 | /// An interface for connecting to the presence datastore |
44 | /// </summary> | 46 | /// </summary> |
45 | public interface IPresenceData | 47 | public interface IPresenceData |
46 | { | 48 | { |
47 | bool Store(PresenceData data); | 49 | bool Store(PresenceData data); |
48 | 50 | ||
49 | PresenceData Get(UUID principalID); | 51 | PresenceData Get(UUID sessionID); |
50 | 52 | void LogoutRegionAgents(UUID regionID); | |
51 | bool SetUserDataItem(UUID principalID, string item, string value); | 53 | bool ReportAgent(UUID sessionID, UUID regionID, string position, string lookAt); |
52 | bool SetRegionDataItem(UUID principalID, string item, string value); | 54 | bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt); |
53 | 55 | PresenceData[] Get(string field, string data); | |
54 | bool Delete(UUID regionID); | 56 | void Prune(string userID); |
57 | bool Delete(string field, string val); | ||
55 | } | 58 | } |
56 | } | 59 | } |
diff --git a/OpenSim/Data/IUserAccountData.cs b/OpenSim/Data/IUserAccountData.cs index 6bec188..5ebe7d3 100644 --- a/OpenSim/Data/IUserAccountData.cs +++ b/OpenSim/Data/IUserAccountData.cs | |||
@@ -36,20 +36,17 @@ namespace OpenSim.Data | |||
36 | { | 36 | { |
37 | public UUID PrincipalID; | 37 | public UUID PrincipalID; |
38 | public UUID ScopeID; | 38 | public UUID ScopeID; |
39 | public string FirstName; | ||
40 | public string LastName; | ||
39 | public Dictionary<string, object> Data; | 41 | public Dictionary<string, object> Data; |
40 | } | 42 | } |
41 | 43 | ||
42 | /// <summary> | 44 | /// <summary> |
43 | /// An interface for connecting to the authentication datastore | 45 | /// An interface for connecting to the user accounts datastore |
44 | /// </summary> | 46 | /// </summary> |
45 | public interface IUserAccountData | 47 | public interface IUserAccountData |
46 | { | 48 | { |
47 | UserAccountData Get(UUID principalID, UUID ScopeID); | 49 | UserAccountData[] Get(string[] fields, string[] values); |
48 | 50 | bool Store(UserAccountData data, UUID principalID, string token); | |
49 | List<UserAccountData> Query(UUID principalID, UUID ScopeID, string query); | ||
50 | |||
51 | bool Store(UserAccountData data); | ||
52 | |||
53 | bool SetDataItem(UUID principalID, string item, string value); | ||
54 | } | 51 | } |
55 | } | 52 | } |
diff --git a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs index 2d92cb1..01750d8 100644 --- a/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs +++ b/OpenSim/Data/MSSQL/MSSQLUserAccountData.cs | |||
@@ -168,6 +168,11 @@ namespace OpenSim.Data.MSSQL | |||
168 | return true; | 168 | return true; |
169 | } | 169 | } |
170 | 170 | ||
171 | public bool Store(UserAccountData data, UUID principalID, string token) | ||
172 | { | ||
173 | return false; | ||
174 | } | ||
175 | |||
171 | public bool SetDataItem(UUID principalID, string item, string value) | 176 | public bool SetDataItem(UUID principalID, string item, string value) |
172 | { | 177 | { |
173 | string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item); | 178 | string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item); |
@@ -184,5 +189,10 @@ namespace OpenSim.Data.MSSQL | |||
184 | } | 189 | } |
185 | return false; | 190 | return false; |
186 | } | 191 | } |
192 | |||
193 | public UserAccountData[] Get(string[] keys, string[] vals) | ||
194 | { | ||
195 | return null; | ||
196 | } | ||
187 | } | 197 | } |
188 | } | 198 | } |
diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index e51dc22..5a9b01b 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs | |||
@@ -138,7 +138,14 @@ namespace OpenSim.Data | |||
138 | cmd.CommandText = kvp.Value; | 138 | cmd.CommandText = kvp.Value; |
139 | // we need to up the command timeout to infinite as we might be doing long migrations. | 139 | // we need to up the command timeout to infinite as we might be doing long migrations. |
140 | cmd.CommandTimeout = 0; | 140 | cmd.CommandTimeout = 0; |
141 | cmd.ExecuteNonQuery(); | 141 | try |
142 | { | ||
143 | cmd.ExecuteNonQuery(); | ||
144 | } | ||
145 | catch (Exception e) | ||
146 | { | ||
147 | m_log.Debug("[MIGRATIONS]: An error has occurred in the migration. This may mean you could see errors trying to run OpenSim. If you see database related errors, you will need to fix the issue manually. Continuing."); | ||
148 | } | ||
142 | 149 | ||
143 | if (version == 0) | 150 | if (version == 0) |
144 | { | 151 | { |
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index b2bd5f6..873d6d4 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | |||
@@ -177,6 +177,8 @@ namespace OpenSim.Data.MySQL | |||
177 | result.Add(row); | 177 | result.Add(row); |
178 | } | 178 | } |
179 | 179 | ||
180 | reader.Close(); | ||
181 | |||
180 | CloseReaderCommand(cmd); | 182 | CloseReaderCommand(cmd); |
181 | 183 | ||
182 | return result.ToArray(); | 184 | return result.ToArray(); |
diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs new file mode 100644 index 0000000..72b8a0c --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | |||
38 | namespace OpenSim.Data.MySQL | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// A MySQL Interface for the Grid Server | ||
42 | /// </summary> | ||
43 | public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>, | ||
44 | IPresenceData | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | public MySQLPresenceData(string connectionString, string realm) : | ||
49 | base(connectionString, realm, "Presence") | ||
50 | { | ||
51 | } | ||
52 | |||
53 | public PresenceData Get(UUID sessionID) | ||
54 | { | ||
55 | PresenceData[] ret = Get("SessionID", | ||
56 | sessionID.ToString()); | ||
57 | |||
58 | if (ret.Length == 0) | ||
59 | return null; | ||
60 | |||
61 | return ret[0]; | ||
62 | } | ||
63 | |||
64 | public void LogoutRegionAgents(UUID regionID) | ||
65 | { | ||
66 | MySqlCommand cmd = new MySqlCommand(); | ||
67 | |||
68 | cmd.CommandText = String.Format("update {0} set Online='false' where `RegionID`=?RegionID", m_Realm); | ||
69 | |||
70 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
71 | |||
72 | ExecuteNonQuery(cmd); | ||
73 | } | ||
74 | |||
75 | public bool ReportAgent(UUID sessionID, UUID regionID, string position, | ||
76 | string lookAt) | ||
77 | { | ||
78 | PresenceData[] pd = Get("SessionID", sessionID.ToString()); | ||
79 | if (pd.Length == 0) | ||
80 | return false; | ||
81 | |||
82 | MySqlCommand cmd = new MySqlCommand(); | ||
83 | |||
84 | cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, Position=?Position, LookAt=?LookAt', Online='true' where `SessionID`=?SessionID", m_Realm); | ||
85 | |||
86 | cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); | ||
87 | cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); | ||
88 | cmd.Parameters.AddWithValue("?Position", position); | ||
89 | cmd.Parameters.AddWithValue("?LookAt", lookAt); | ||
90 | |||
91 | if (ExecuteNonQuery(cmd) == 0) | ||
92 | return false; | ||
93 | |||
94 | return true; | ||
95 | } | ||
96 | |||
97 | public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
98 | { | ||
99 | PresenceData[] pd = Get("UserID", userID); | ||
100 | if (pd.Length == 0) | ||
101 | return false; | ||
102 | |||
103 | MySqlCommand cmd = new MySqlCommand(); | ||
104 | |||
105 | cmd.CommandText = String.Format("update {0} set HomeRegionID=?HomeRegionID, HomePosition=?HomePosition, HomeLookAt=?HomeLookAt where UserID=?UserID", m_Realm); | ||
106 | |||
107 | cmd.Parameters.AddWithValue("?UserID", userID); | ||
108 | cmd.Parameters.AddWithValue("?HomeRegionID", regionID.ToString()); | ||
109 | cmd.Parameters.AddWithValue("?HomePosition", position); | ||
110 | cmd.Parameters.AddWithValue("?HomeLookAt", lookAt); | ||
111 | |||
112 | if (ExecuteNonQuery(cmd) == 0) | ||
113 | return false; | ||
114 | |||
115 | return true; | ||
116 | } | ||
117 | |||
118 | public void Prune(string userID) | ||
119 | { | ||
120 | MySqlCommand cmd = new MySqlCommand(); | ||
121 | |||
122 | cmd.CommandText = String.Format("select * from {0} where UserID=?UserID", m_Realm); | ||
123 | |||
124 | cmd.Parameters.AddWithValue("?UserID", userID); | ||
125 | |||
126 | IDataReader reader = ExecuteReader(cmd); | ||
127 | |||
128 | List<UUID> deleteSessions = new List<UUID>(); | ||
129 | int online = 0; | ||
130 | |||
131 | while(reader.Read()) | ||
132 | { | ||
133 | if (bool.Parse(reader["Online"].ToString())) | ||
134 | online++; | ||
135 | else | ||
136 | deleteSessions.Add(new UUID(reader["SessionID"].ToString())); | ||
137 | } | ||
138 | |||
139 | if (online == 0 && deleteSessions.Count > 0) | ||
140 | deleteSessions.RemoveAt(0); | ||
141 | |||
142 | reader.Close(); | ||
143 | CloseReaderCommand(cmd); | ||
144 | |||
145 | foreach (UUID s in deleteSessions) | ||
146 | Delete("SessionID", s.ToString()); | ||
147 | } | ||
148 | } | ||
149 | } | ||
diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index d48144d..e2ce6d1 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs | |||
@@ -35,146 +35,16 @@ using MySql.Data.MySqlClient; | |||
35 | 35 | ||
36 | namespace OpenSim.Data.MySQL | 36 | namespace OpenSim.Data.MySQL |
37 | { | 37 | { |
38 | public class MySqlUserAccountData : MySqlFramework, IUserAccountData | 38 | public class MySqlUserAccountData : MySQLGenericTableHandler<UserAccountData>, IUserAccountData |
39 | { | 39 | { |
40 | private string m_Realm; | ||
41 | private List<string> m_ColumnNames = null; | ||
42 | // private int m_LastExpire = 0; | ||
43 | |||
44 | public MySqlUserAccountData(string connectionString, string realm) | 40 | public MySqlUserAccountData(string connectionString, string realm) |
45 | : base(connectionString) | 41 | : base(connectionString, realm, "UserAccount") |
46 | { | ||
47 | m_Realm = realm; | ||
48 | |||
49 | Migration m = new Migration(m_Connection, GetType().Assembly, "UserStore"); | ||
50 | m.Update(); | ||
51 | } | ||
52 | |||
53 | public List<UserAccountData> Query(UUID principalID, UUID scopeID, string query) | ||
54 | { | 42 | { |
55 | return null; | ||
56 | } | ||
57 | |||
58 | public UserAccountData Get(UUID principalID, UUID scopeID) | ||
59 | { | ||
60 | UserAccountData ret = new UserAccountData(); | ||
61 | ret.Data = new Dictionary<string, object>(); | ||
62 | |||
63 | string command = "select * from `"+m_Realm+"` where UUID = ?principalID"; | ||
64 | if (scopeID != UUID.Zero) | ||
65 | command += " and ScopeID = ?scopeID"; | ||
66 | |||
67 | MySqlCommand cmd = new MySqlCommand(command); | ||
68 | |||
69 | cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); | ||
70 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
71 | |||
72 | IDataReader result = ExecuteReader(cmd); | ||
73 | |||
74 | if (result.Read()) | ||
75 | { | ||
76 | ret.PrincipalID = principalID; | ||
77 | UUID scope; | ||
78 | UUID.TryParse(result["ScopeID"].ToString(), out scope); | ||
79 | ret.ScopeID = scope; | ||
80 | |||
81 | if (m_ColumnNames == null) | ||
82 | { | ||
83 | m_ColumnNames = new List<string>(); | ||
84 | |||
85 | DataTable schemaTable = result.GetSchemaTable(); | ||
86 | foreach (DataRow row in schemaTable.Rows) | ||
87 | m_ColumnNames.Add(row["ColumnName"].ToString()); | ||
88 | } | ||
89 | |||
90 | foreach (string s in m_ColumnNames) | ||
91 | { | ||
92 | if (s == "UUID") | ||
93 | continue; | ||
94 | if (s == "ScopeID") | ||
95 | continue; | ||
96 | |||
97 | ret.Data[s] = result[s].ToString(); | ||
98 | } | ||
99 | |||
100 | result.Close(); | ||
101 | CloseReaderCommand(cmd); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | result.Close(); | ||
107 | CloseReaderCommand(cmd); | ||
108 | |||
109 | return null; | ||
110 | } | 43 | } |
111 | 44 | ||
112 | public bool Store(UserAccountData data) | 45 | public bool Store(UserAccountData data, UUID principalID, string token) |
113 | { | 46 | { |
114 | if (data.Data.ContainsKey("UUID")) | 47 | return Store(data); |
115 | data.Data.Remove("UUID"); | ||
116 | if (data.Data.ContainsKey("ScopeID")) | ||
117 | data.Data.Remove("ScopeID"); | ||
118 | |||
119 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
120 | |||
121 | MySqlCommand cmd = new MySqlCommand(); | ||
122 | |||
123 | string update = "update `"+m_Realm+"` set "; | ||
124 | bool first = true; | ||
125 | foreach (string field in fields) | ||
126 | { | ||
127 | if (!first) | ||
128 | update += ", "; | ||
129 | update += "`" + field + "` = ?"+field; | ||
130 | |||
131 | first = false; | ||
132 | |||
133 | cmd.Parameters.AddWithValue("?"+field, data.Data[field]); | ||
134 | } | ||
135 | |||
136 | update += " where UUID = ?principalID"; | ||
137 | |||
138 | if (data.ScopeID != UUID.Zero) | ||
139 | update += " and ScopeID = ?scopeID"; | ||
140 | |||
141 | cmd.CommandText = update; | ||
142 | cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString()); | ||
143 | cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); | ||
144 | |||
145 | if (ExecuteNonQuery(cmd) < 1) | ||
146 | { | ||
147 | string insert = "insert into `" + m_Realm + "` (`UUID`, `ScopeID`, `" + | ||
148 | String.Join("`, `", fields) + | ||
149 | "`) values (?principalID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; | ||
150 | |||
151 | cmd.CommandText = insert; | ||
152 | |||
153 | if (ExecuteNonQuery(cmd) < 1) | ||
154 | { | ||
155 | cmd.Dispose(); | ||
156 | return false; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | cmd.Dispose(); | ||
161 | |||
162 | return true; | ||
163 | } | ||
164 | |||
165 | public bool SetDataItem(UUID principalID, string item, string value) | ||
166 | { | ||
167 | MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + | ||
168 | "` set `" + item + "` = ?" + item + " where UUID = ?UUID"); | ||
169 | |||
170 | |||
171 | cmd.Parameters.AddWithValue("?"+item, value); | ||
172 | cmd.Parameters.AddWithValue("?UUID", principalID.ToString()); | ||
173 | |||
174 | if (ExecuteNonQuery(cmd) > 0) | ||
175 | return true; | ||
176 | |||
177 | return false; | ||
178 | } | 48 | } |
179 | } | 49 | } |
180 | } | 50 | } |
diff --git a/OpenSim/Data/MySQL/Resources/001_Friends.sql b/OpenSim/Data/MySQL/Resources/001_Friends.sql new file mode 100644 index 0000000..e158a2c --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/001_Friends.sql | |||
@@ -0,0 +1,9 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | CREATE TABLE `Friends` ( | ||
4 | `PrincipalID` CHAR(36) NOT NULL, | ||
5 | `FriendID` VARCHAR(255) NOT NULL, | ||
6 | `Flags` CHAR(16) NOT NULL DEFAULT '0' | ||
7 | ) ENGINE=InnoDB; | ||
8 | |||
9 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/001_Presence.sql b/OpenSim/Data/MySQL/Resources/001_Presence.sql new file mode 100644 index 0000000..b8abaf7 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/001_Presence.sql | |||
@@ -0,0 +1,15 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | CREATE TABLE `Presence` ( | ||
4 | `UserID` VARCHAR(255) NOT NULL, | ||
5 | `RegionID` CHAR(36) NOT NULL, | ||
6 | `SessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
7 | `SecureSessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
8 | `Online` CHAR(5) NOT NULL DEFAULT 'false', | ||
9 | `Login` CHAR(16) NOT NULL DEFAULT '0', | ||
10 | `Logout` CHAR(16) NOT NULL DEFAULT '0', | ||
11 | `Position` CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
12 | `LookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>' | ||
13 | ) ENGINE=InnoDB; | ||
14 | |||
15 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/001_UserAccount.sql b/OpenSim/Data/MySQL/Resources/001_UserAccount.sql new file mode 100644 index 0000000..07da571 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/001_UserAccount.sql | |||
@@ -0,0 +1,13 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | CREATE TABLE `UserAccounts` ( | ||
4 | `PrincipalID` CHAR(36) NOT NULL, | ||
5 | `ScopeID` CHAR(36) NOT NULL, | ||
6 | `FirstName` VARCHAR(64) NOT NULL, | ||
7 | `LastName` VARCHAR(64) NOT NULL, | ||
8 | `Email` VARCHAR(64), | ||
9 | `ServiceURLs` TEXT, | ||
10 | `Created` INT(11) | ||
11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; | ||
12 | |||
13 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/002_Friends.sql b/OpenSim/Data/MySQL/Resources/002_Friends.sql new file mode 100644 index 0000000..5ff6438 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/002_Friends.sql | |||
@@ -0,0 +1,5 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | INSERT INTO Friends (PrincipalID, FriendID, Flags) SELECT ownerID, friendID, friendPerms FROM userfriends; | ||
4 | |||
5 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/002_Presence.sql b/OpenSim/Data/MySQL/Resources/002_Presence.sql new file mode 100644 index 0000000..e65f105 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/002_Presence.sql | |||
@@ -0,0 +1,7 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | ALTER TABLE Presence ADD COLUMN `HomeRegionID` CHAR(36) NOT NULL; | ||
4 | ALTER TABLE Presence ADD COLUMN `HomePosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>'; | ||
5 | ALTER TABLE Presence ADD COLUMN `HomeLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>'; | ||
6 | |||
7 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/002_UserAccount.sql b/OpenSim/Data/MySQL/Resources/002_UserAccount.sql new file mode 100644 index 0000000..ad2ddda --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/002_UserAccount.sql | |||
@@ -0,0 +1,5 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, lastname AS LastName, email as Email, CONCAT('AssetServerURI=', userAssetURI, ' InventoryServerURI=', userInventoryURI, ' GatewayURI= HomeURI=') AS ServiceURLs, created as Created FROM users; | ||
4 | |||
5 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/003_Presence.sql b/OpenSim/Data/MySQL/Resources/003_Presence.sql new file mode 100644 index 0000000..0efefa8 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/003_Presence.sql | |||
@@ -0,0 +1,6 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | CREATE UNIQUE INDEX SessionID ON Presence(SessionID); | ||
4 | CREATE INDEX UserID ON Presence(UserID); | ||
5 | |||
6 | COMMIT; | ||
diff --git a/OpenSim/Data/MySQL/Resources/003_UserAccount.sql b/OpenSim/Data/MySQL/Resources/003_UserAccount.sql new file mode 100644 index 0000000..e42d93b --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/003_UserAccount.sql | |||
@@ -0,0 +1,9 @@ | |||
1 | BEGIN; | ||
2 | |||
3 | CREATE UNIQUE INDEX PrincipalID ON UserAccounts(PrincipalID); | ||
4 | CREATE INDEX Email ON UserAccounts(Email); | ||
5 | CREATE INDEX FirstName ON UserAccounts(FirstName); | ||
6 | CREATE INDEX LastName ON UserAccounts(LastName); | ||
7 | CREATE INDEX Name ON UserAccounts(FirstName,LastName); | ||
8 | |||
9 | COMMIT; | ||
diff --git a/OpenSim/Data/Null/NullPresenceData.cs b/OpenSim/Data/Null/NullPresenceData.cs new file mode 100644 index 0000000..52fdc6f --- /dev/null +++ b/OpenSim/Data/Null/NullPresenceData.cs | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Data; | ||
34 | |||
35 | namespace OpenSim.Data.Null | ||
36 | { | ||
37 | public class NullPresenceData : IPresenceData | ||
38 | { | ||
39 | Dictionary<UUID, PresenceData> m_presenceData = new Dictionary<UUID, PresenceData>(); | ||
40 | |||
41 | public NullPresenceData(string connectionString, string realm) | ||
42 | { | ||
43 | //Console.WriteLine("[XXX] NullRegionData constructor"); | ||
44 | // Let's stick in a test presence | ||
45 | PresenceData p = new PresenceData(); | ||
46 | p.SessionID = UUID.Zero; | ||
47 | p.UserID = UUID.Zero.ToString(); | ||
48 | p.Data = new Dictionary<string, string>(); | ||
49 | p.Data["Online"] = "true"; | ||
50 | m_presenceData.Add(UUID.Zero, p); | ||
51 | } | ||
52 | |||
53 | public bool Store(PresenceData data) | ||
54 | { | ||
55 | m_presenceData[data.SessionID] = data; | ||
56 | return true; | ||
57 | } | ||
58 | |||
59 | public PresenceData Get(UUID sessionID) | ||
60 | { | ||
61 | if (m_presenceData.ContainsKey(sessionID)) | ||
62 | return m_presenceData[sessionID]; | ||
63 | |||
64 | return null; | ||
65 | } | ||
66 | |||
67 | public void LogoutRegionAgents(UUID regionID) | ||
68 | { | ||
69 | List<UUID> toBeDeleted = new List<UUID>(); | ||
70 | foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData) | ||
71 | if (kvp.Value.RegionID == regionID) | ||
72 | toBeDeleted.Add(kvp.Key); | ||
73 | |||
74 | foreach (UUID u in toBeDeleted) | ||
75 | m_presenceData.Remove(u); | ||
76 | } | ||
77 | |||
78 | public bool ReportAgent(UUID sessionID, UUID regionID, string position, string lookAt) | ||
79 | { | ||
80 | if (m_presenceData.ContainsKey(sessionID)) | ||
81 | { | ||
82 | m_presenceData[sessionID].RegionID = regionID; | ||
83 | m_presenceData[sessionID].Data["Position"] = position; | ||
84 | m_presenceData[sessionID].Data["LookAt"] = lookAt; | ||
85 | return true; | ||
86 | } | ||
87 | |||
88 | return false; | ||
89 | } | ||
90 | |||
91 | public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
92 | { | ||
93 | bool foundone = false; | ||
94 | foreach (PresenceData p in m_presenceData.Values) | ||
95 | { | ||
96 | if (p.UserID == userID) | ||
97 | { | ||
98 | p.Data["HomeRegionID"] = regionID.ToString(); | ||
99 | p.Data["HomePosition"] = position.ToString(); | ||
100 | p.Data["HomeLookAt"] = lookAt.ToString(); | ||
101 | foundone = true; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | return foundone; | ||
106 | } | ||
107 | |||
108 | public PresenceData[] Get(string field, string data) | ||
109 | { | ||
110 | List<PresenceData> presences = new List<PresenceData>(); | ||
111 | if (field == "UserID") | ||
112 | { | ||
113 | foreach (PresenceData p in m_presenceData.Values) | ||
114 | if (p.UserID == data) | ||
115 | presences.Add(p); | ||
116 | return presences.ToArray(); | ||
117 | } | ||
118 | else if (field == "SessionID") | ||
119 | { | ||
120 | UUID session = UUID.Zero; | ||
121 | if (!UUID.TryParse(data, out session)) | ||
122 | return presences.ToArray(); | ||
123 | |||
124 | if (m_presenceData.ContainsKey(session)) | ||
125 | { | ||
126 | presences.Add(m_presenceData[session]); | ||
127 | return presences.ToArray(); | ||
128 | } | ||
129 | } | ||
130 | else if (field == "RegionID") | ||
131 | { | ||
132 | UUID region = UUID.Zero; | ||
133 | if (!UUID.TryParse(data, out region)) | ||
134 | return presences.ToArray(); | ||
135 | foreach (PresenceData p in m_presenceData.Values) | ||
136 | if (p.RegionID == region) | ||
137 | presences.Add(p); | ||
138 | return presences.ToArray(); | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | foreach (PresenceData p in m_presenceData.Values) | ||
143 | { | ||
144 | if (p.Data.ContainsKey(field) && p.Data[field] == data) | ||
145 | presences.Add(p); | ||
146 | } | ||
147 | return presences.ToArray(); | ||
148 | } | ||
149 | |||
150 | return presences.ToArray(); | ||
151 | } | ||
152 | |||
153 | public void Prune(string userID) | ||
154 | { | ||
155 | List<UUID> deleteSessions = new List<UUID>(); | ||
156 | int online = 0; | ||
157 | |||
158 | foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData) | ||
159 | { | ||
160 | bool on = false; | ||
161 | if (bool.TryParse(kvp.Value.Data["Online"], out on) && on) | ||
162 | online++; | ||
163 | else | ||
164 | deleteSessions.Add(kvp.Key); | ||
165 | } | ||
166 | if (online == 0 && deleteSessions.Count > 0) | ||
167 | deleteSessions.RemoveAt(0); | ||
168 | |||
169 | foreach (UUID s in deleteSessions) | ||
170 | m_presenceData.Remove(s); | ||
171 | |||
172 | } | ||
173 | |||
174 | public bool Delete(string field, string data) | ||
175 | { | ||
176 | List<UUID> presences = new List<UUID>(); | ||
177 | if (field == "UserID") | ||
178 | { | ||
179 | foreach (KeyValuePair<UUID, PresenceData> p in m_presenceData) | ||
180 | if (p.Value.UserID == data) | ||
181 | presences.Add(p.Key); | ||
182 | } | ||
183 | else if (field == "SessionID") | ||
184 | { | ||
185 | UUID session = UUID.Zero; | ||
186 | if (UUID.TryParse(data, out session)) | ||
187 | { | ||
188 | if (m_presenceData.ContainsKey(session)) | ||
189 | { | ||
190 | presences.Add(session); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | else if (field == "RegionID") | ||
195 | { | ||
196 | UUID region = UUID.Zero; | ||
197 | if (UUID.TryParse(data, out region)) | ||
198 | { | ||
199 | foreach (KeyValuePair<UUID, PresenceData> p in m_presenceData) | ||
200 | if (p.Value.RegionID == region) | ||
201 | presences.Add(p.Key); | ||
202 | } | ||
203 | } | ||
204 | else | ||
205 | { | ||
206 | foreach (KeyValuePair<UUID, PresenceData> p in m_presenceData) | ||
207 | { | ||
208 | if (p.Value.Data.ContainsKey(field) && p.Value.Data[field] == data) | ||
209 | presences.Add(p.Key); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | foreach (UUID u in presences) | ||
214 | m_presenceData.Remove(u); | ||
215 | |||
216 | if (presences.Count == 0) | ||
217 | return false; | ||
218 | |||
219 | return true; | ||
220 | } | ||
221 | |||
222 | } | ||
223 | } | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index d6a82ef..f5d30b7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -44,1088 +44,50 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; | |||
44 | 44 | ||
45 | namespace OpenSim.Region.CoreModules.Avatar.Friends | 45 | namespace OpenSim.Region.CoreModules.Avatar.Friends |
46 | { | 46 | { |
47 | /* | 47 | public class FriendsModule : ISharedRegionModule, IFriendsModule |
48 | This module handles adding/removing friends, and the the presence | ||
49 | notification process for login/logoff of friends. | ||
50 | |||
51 | The presence notification works as follows: | ||
52 | - After the user initially connects to a region (so we now have a UDP | ||
53 | connection to work with), this module fetches the friends of user | ||
54 | (those are cached), their on-/offline status, and info about the | ||
55 | region they are in from the MessageServer. | ||
56 | - (*) It then informs the user about the on-/offline status of her friends. | ||
57 | - It then informs all online friends currently on this region-server about | ||
58 | user's new online status (this will save some network traffic, as local | ||
59 | messages don't have to be transferred inter-region, and it will be all | ||
60 | that has to be done in Standalone Mode). | ||
61 | - For the rest of the online friends (those not on this region-server), | ||
62 | this module uses the provided region-information to map users to | ||
63 | regions, and sends one notification to every region containing the | ||
64 | friends to inform on that server. | ||
65 | - The region-server will handle that in the following way: | ||
66 | - If it finds the friend, it informs her about the user being online. | ||
67 | - If it doesn't find the friend (maybe she TPed away in the meantime), | ||
68 | it stores that information. | ||
69 | - After it processed all friends, it returns the list of friends it | ||
70 | couldn't find. | ||
71 | - If this list isn't empty, the FriendsModule re-requests information | ||
72 | about those online friends that have been missed and starts at (*) | ||
73 | again until all friends have been found, or until it tried 3 times | ||
74 | (to prevent endless loops due to some uncaught error). | ||
75 | |||
76 | NOTE: Online/Offline notifications don't need to be sent on region change. | ||
77 | |||
78 | We implement two XMLRpc handlers here, handling all the inter-region things | ||
79 | we have to handle: | ||
80 | - On-/Offline-Notifications (bulk) | ||
81 | - Terminate Friendship messages (single) | ||
82 | */ | ||
83 | |||
84 | public class FriendsModule : IRegionModule, IFriendsModule | ||
85 | { | 48 | { |
86 | private class Transaction | 49 | public void Initialise(IConfigSource config) |
87 | { | 50 | { |
88 | public UUID agentID; | ||
89 | public string agentName; | ||
90 | public uint count; | ||
91 | |||
92 | public Transaction(UUID agentID, string agentName) | ||
93 | { | ||
94 | this.agentID = agentID; | ||
95 | this.agentName = agentName; | ||
96 | this.count = 1; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
101 | |||
102 | private Cache m_friendLists = new Cache(CacheFlags.AllowUpdate); | ||
103 | |||
104 | private Dictionary<UUID, ulong> m_rootAgents = new Dictionary<UUID, ulong>(); | ||
105 | |||
106 | private Dictionary<UUID, UUID> m_pendingCallingcardRequests = new Dictionary<UUID,UUID>(); | ||
107 | |||
108 | private Scene m_initialScene; // saves a lookup if we don't have a specific scene | ||
109 | private Dictionary<ulong, Scene> m_scenes = new Dictionary<ulong,Scene>(); | ||
110 | private IMessageTransferModule m_TransferModule = null; | ||
111 | |||
112 | private IGridService m_gridServices = null; | ||
113 | |||
114 | #region IRegionModule Members | ||
115 | |||
116 | public void Initialise(Scene scene, IConfigSource config) | ||
117 | { | ||
118 | lock (m_scenes) | ||
119 | { | ||
120 | if (m_scenes.Count == 0) | ||
121 | { | ||
122 | MainServer.Instance.AddXmlRPCHandler("presence_update_bulk", processPresenceUpdateBulk); | ||
123 | MainServer.Instance.AddXmlRPCHandler("terminate_friend", processTerminateFriend); | ||
124 | m_friendLists.DefaultTTL = new TimeSpan(1, 0, 0); // store entries for one hour max | ||
125 | m_initialScene = scene; | ||
126 | } | ||
127 | |||
128 | if (!m_scenes.ContainsKey(scene.RegionInfo.RegionHandle)) | ||
129 | m_scenes[scene.RegionInfo.RegionHandle] = scene; | ||
130 | } | ||
131 | |||
132 | scene.RegisterModuleInterface<IFriendsModule>(this); | ||
133 | |||
134 | scene.EventManager.OnNewClient += OnNewClient; | ||
135 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | ||
136 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | ||
137 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; | ||
138 | scene.EventManager.OnClientClosed += ClientClosed; | ||
139 | } | 51 | } |
140 | 52 | ||
141 | public void PostInitialise() | 53 | public void PostInitialise() |
142 | { | 54 | { |
143 | if (m_scenes.Count > 0) | ||
144 | { | ||
145 | m_TransferModule = m_initialScene.RequestModuleInterface<IMessageTransferModule>(); | ||
146 | m_gridServices = m_initialScene.GridService; | ||
147 | } | ||
148 | if (m_TransferModule == null) | ||
149 | m_log.Error("[FRIENDS]: Unable to find a message transfer module, friendship offers will not work"); | ||
150 | } | ||
151 | |||
152 | public void Close() | ||
153 | { | ||
154 | } | ||
155 | |||
156 | public string Name | ||
157 | { | ||
158 | get { return "FriendsModule"; } | ||
159 | } | ||
160 | |||
161 | public bool IsSharedModule | ||
162 | { | ||
163 | get { return true; } | ||
164 | } | ||
165 | |||
166 | #endregion | ||
167 | |||
168 | #region IInterregionFriendsComms | ||
169 | |||
170 | public List<UUID> InformFriendsInOtherRegion(UUID agentId, ulong destRegionHandle, List<UUID> friends, bool online) | ||
171 | { | ||
172 | List<UUID> tpdAway = new List<UUID>(); | ||
173 | |||
174 | // destRegionHandle is a region on another server | ||
175 | uint x = 0, y = 0; | ||
176 | Utils.LongToUInts(destRegionHandle, out x, out y); | ||
177 | GridRegion info = m_gridServices.GetRegionByPosition(m_initialScene.RegionInfo.ScopeID, (int)x, (int)y); | ||
178 | if (info != null) | ||
179 | { | ||
180 | string httpServer = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/presence_update_bulk"; | ||
181 | |||
182 | Hashtable reqParams = new Hashtable(); | ||
183 | reqParams["agentID"] = agentId.ToString(); | ||
184 | reqParams["agentOnline"] = online; | ||
185 | int count = 0; | ||
186 | foreach (UUID uuid in friends) | ||
187 | { | ||
188 | reqParams["friendID_" + count++] = uuid.ToString(); | ||
189 | } | ||
190 | reqParams["friendCount"] = count; | ||
191 | |||
192 | IList parameters = new ArrayList(); | ||
193 | parameters.Add(reqParams); | ||
194 | try | ||
195 | { | ||
196 | XmlRpcRequest request = new XmlRpcRequest("presence_update_bulk", parameters); | ||
197 | XmlRpcResponse response = request.Send(httpServer, 5000); | ||
198 | Hashtable respData = (Hashtable)response.Value; | ||
199 | |||
200 | count = (int)respData["friendCount"]; | ||
201 | for (int i = 0; i < count; ++i) | ||
202 | { | ||
203 | UUID uuid; | ||
204 | if (UUID.TryParse((string)respData["friendID_" + i], out uuid)) tpdAway.Add(uuid); | ||
205 | } | ||
206 | } | ||
207 | catch (WebException e) | ||
208 | { | ||
209 | // Ignore connect failures, simulators come and go | ||
210 | // | ||
211 | if (!e.Message.Contains("ConnectFailure")) | ||
212 | { | ||
213 | m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e); | ||
214 | } | ||
215 | } | ||
216 | catch (Exception e) | ||
217 | { | ||
218 | m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e); | ||
219 | } | ||
220 | } | ||
221 | else m_log.WarnFormat("[OGS1 GRID SERVICES]: Couldn't find region {0}???", destRegionHandle); | ||
222 | |||
223 | return tpdAway; | ||
224 | } | ||
225 | |||
226 | public bool TriggerTerminateFriend(ulong destRegionHandle, UUID agentID, UUID exFriendID) | ||
227 | { | ||
228 | // destRegionHandle is a region on another server | ||
229 | uint x = 0, y = 0; | ||
230 | Utils.LongToUInts(destRegionHandle, out x, out y); | ||
231 | GridRegion info = m_gridServices.GetRegionByPosition(m_initialScene.RegionInfo.ScopeID, (int)x, (int)y); | ||
232 | if (info == null) | ||
233 | { | ||
234 | m_log.WarnFormat("[OGS1 GRID SERVICES]: Couldn't find region {0}", destRegionHandle); | ||
235 | return false; // region not found??? | ||
236 | } | ||
237 | |||
238 | string httpServer = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/presence_update_bulk"; | ||
239 | |||
240 | Hashtable reqParams = new Hashtable(); | ||
241 | reqParams["agentID"] = agentID.ToString(); | ||
242 | reqParams["friendID"] = exFriendID.ToString(); | ||
243 | |||
244 | IList parameters = new ArrayList(); | ||
245 | parameters.Add(reqParams); | ||
246 | try | ||
247 | { | ||
248 | XmlRpcRequest request = new XmlRpcRequest("terminate_friend", parameters); | ||
249 | XmlRpcResponse response = request.Send(httpServer, 5000); | ||
250 | Hashtable respData = (Hashtable)response.Value; | ||
251 | |||
252 | return (bool)respData["success"]; | ||
253 | } | ||
254 | catch (Exception e) | ||
255 | { | ||
256 | m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e); | ||
257 | return false; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | #endregion | ||
262 | |||
263 | #region Incoming XMLRPC messages | ||
264 | /// <summary> | ||
265 | /// Receive presence information changes about clients in other regions. | ||
266 | /// </summary> | ||
267 | /// <param name="req"></param> | ||
268 | /// <returns></returns> | ||
269 | public XmlRpcResponse processPresenceUpdateBulk(XmlRpcRequest req, IPEndPoint remoteClient) | ||
270 | { | ||
271 | Hashtable requestData = (Hashtable)req.Params[0]; | ||
272 | |||
273 | List<UUID> friendsNotHere = new List<UUID>(); | ||
274 | |||
275 | // this is called with the expectation that all the friends in the request are on this region-server. | ||
276 | // But as some time passed since we checked (on the other region-server, via the MessagingServer), | ||
277 | // some of the friends might have teleported away. | ||
278 | // Actually, even now, between this line and the sending below, some people could TP away. So, | ||
279 | // we'll have to lock the m_rootAgents list for the duration to prevent/delay that. | ||
280 | lock (m_rootAgents) | ||
281 | { | ||
282 | List<ScenePresence> friendsHere = new List<ScenePresence>(); | ||
283 | |||
284 | try | ||
285 | { | ||
286 | UUID agentID = new UUID((string)requestData["agentID"]); | ||
287 | bool agentOnline = (bool)requestData["agentOnline"]; | ||
288 | int count = (int)requestData["friendCount"]; | ||
289 | for (int i = 0; i < count; ++i) | ||
290 | { | ||
291 | UUID uuid; | ||
292 | if (UUID.TryParse((string)requestData["friendID_" + i], out uuid)) | ||
293 | { | ||
294 | if (m_rootAgents.ContainsKey(uuid)) friendsHere.Add(GetRootPresenceFromAgentID(uuid)); | ||
295 | else friendsNotHere.Add(uuid); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | // now send, as long as they are still here... | ||
300 | UUID[] agentUUID = new UUID[] { agentID }; | ||
301 | if (agentOnline) | ||
302 | { | ||
303 | foreach (ScenePresence agent in friendsHere) | ||
304 | { | ||
305 | agent.ControllingClient.SendAgentOnline(agentUUID); | ||
306 | } | ||
307 | } | ||
308 | else | ||
309 | { | ||
310 | foreach (ScenePresence agent in friendsHere) | ||
311 | { | ||
312 | agent.ControllingClient.SendAgentOffline(agentUUID); | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | catch(Exception e) | ||
317 | { | ||
318 | m_log.Warn("[FRIENDS]: Got exception while parsing presence_update_bulk request:", e); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | // no need to lock anymore; if TPs happen now, worst case is that we have an additional agent in this region, | ||
323 | // which should be caught on the next iteration... | ||
324 | Hashtable result = new Hashtable(); | ||
325 | int idx = 0; | ||
326 | foreach (UUID uuid in friendsNotHere) | ||
327 | { | ||
328 | result["friendID_" + idx++] = uuid.ToString(); | ||
329 | } | ||
330 | result["friendCount"] = idx; | ||
331 | |||
332 | XmlRpcResponse response = new XmlRpcResponse(); | ||
333 | response.Value = result; | ||
334 | |||
335 | return response; | ||
336 | } | ||
337 | |||
338 | public XmlRpcResponse processTerminateFriend(XmlRpcRequest req, IPEndPoint remoteClient) | ||
339 | { | ||
340 | Hashtable requestData = (Hashtable)req.Params[0]; | ||
341 | |||
342 | bool success = false; | ||
343 | |||
344 | UUID agentID; | ||
345 | UUID friendID; | ||
346 | if (requestData.ContainsKey("agentID") && UUID.TryParse((string)requestData["agentID"], out agentID) && | ||
347 | requestData.ContainsKey("friendID") && UUID.TryParse((string)requestData["friendID"], out friendID)) | ||
348 | { | ||
349 | // try to find it and if it is there, prevent it to vanish before we sent the message | ||
350 | lock (m_rootAgents) | ||
351 | { | ||
352 | if (m_rootAgents.ContainsKey(agentID)) | ||
353 | { | ||
354 | m_log.DebugFormat("[FRIEND]: Sending terminate friend {0} to agent {1}", friendID, agentID); | ||
355 | GetRootPresenceFromAgentID(agentID).ControllingClient.SendTerminateFriend(friendID); | ||
356 | success = true; | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | |||
361 | // return whether we were successful | ||
362 | Hashtable result = new Hashtable(); | ||
363 | result["success"] = success; | ||
364 | |||
365 | XmlRpcResponse response = new XmlRpcResponse(); | ||
366 | response.Value = result; | ||
367 | return response; | ||
368 | } | ||
369 | |||
370 | #endregion | ||
371 | |||
372 | #region Scene events | ||
373 | |||
374 | private void OnNewClient(IClientAPI client) | ||
375 | { | ||
376 | // All friends establishment protocol goes over instant message | ||
377 | // There's no way to send a message from the sim | ||
378 | // to a user to 'add a friend' without causing dialog box spam | ||
379 | |||
380 | // Subscribe to instant messages | ||
381 | client.OnInstantMessage += OnInstantMessage; | ||
382 | |||
383 | // Friend list management | ||
384 | client.OnApproveFriendRequest += OnApproveFriendRequest; | ||
385 | client.OnDenyFriendRequest += OnDenyFriendRequest; | ||
386 | client.OnTerminateFriendship += OnTerminateFriendship; | ||
387 | |||
388 | // ... calling card handling... | ||
389 | client.OnOfferCallingCard += OnOfferCallingCard; | ||
390 | client.OnAcceptCallingCard += OnAcceptCallingCard; | ||
391 | client.OnDeclineCallingCard += OnDeclineCallingCard; | ||
392 | |||
393 | // we need this one exactly once per agent session (see comments in the handler below) | ||
394 | client.OnEconomyDataRequest += OnEconomyDataRequest; | ||
395 | |||
396 | // if it leaves, we want to know, too | ||
397 | client.OnLogout += OnLogout; | ||
398 | client.OnGrantUserRights += GrantUserFriendRights; | ||
399 | |||
400 | } | ||
401 | |||
402 | private void ClientClosed(UUID AgentId, Scene scene) | ||
403 | { | ||
404 | // agent's client was closed. As we handle logout in OnLogout, this here has only to handle | ||
405 | // TPing away (root agent is closed) or TPing/crossing in a region far enough away (client | ||
406 | // agent is closed). | ||
407 | // NOTE: In general, this doesn't mean that the agent logged out, just that it isn't around | ||
408 | // in one of the regions here anymore. | ||
409 | lock (m_rootAgents) | ||
410 | { | ||
411 | if (m_rootAgents.ContainsKey(AgentId)) | ||
412 | { | ||
413 | m_rootAgents.Remove(AgentId); | ||
414 | } | ||
415 | } | ||
416 | } | ||
417 | |||
418 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID) | ||
419 | { | ||
420 | lock (m_rootAgents) | ||
421 | { | ||
422 | m_rootAgents[avatar.UUID] = avatar.RegionHandle; | ||
423 | // Claim User! my user! Mine mine mine! | ||
424 | } | ||
425 | } | ||
426 | |||
427 | private void MakeChildAgent(ScenePresence avatar) | ||
428 | { | ||
429 | lock (m_rootAgents) | ||
430 | { | ||
431 | if (m_rootAgents.ContainsKey(avatar.UUID)) | ||
432 | { | ||
433 | // only delete if the region matches. As this is a shared module, the avatar could be | ||
434 | // root agent in another region on this server. | ||
435 | if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) | ||
436 | { | ||
437 | m_rootAgents.Remove(avatar.UUID); | ||
438 | // m_log.Debug("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | #endregion | ||
444 | |||
445 | private ScenePresence GetRootPresenceFromAgentID(UUID AgentID) | ||
446 | { | ||
447 | ScenePresence returnAgent = null; | ||
448 | lock (m_scenes) | ||
449 | { | ||
450 | ScenePresence queryagent = null; | ||
451 | foreach (Scene scene in m_scenes.Values) | ||
452 | { | ||
453 | queryagent = scene.GetScenePresence(AgentID); | ||
454 | if (queryagent != null) | ||
455 | { | ||
456 | if (!queryagent.IsChildAgent) | ||
457 | { | ||
458 | returnAgent = queryagent; | ||
459 | break; | ||
460 | } | ||
461 | } | ||
462 | } | ||
463 | } | ||
464 | return returnAgent; | ||
465 | } | ||
466 | |||
467 | private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) | ||
468 | { | ||
469 | ScenePresence returnAgent = null; | ||
470 | lock (m_scenes) | ||
471 | { | ||
472 | ScenePresence queryagent = null; | ||
473 | foreach (Scene scene in m_scenes.Values) | ||
474 | { | ||
475 | queryagent = scene.GetScenePresence(AgentID); | ||
476 | if (queryagent != null) | ||
477 | { | ||
478 | returnAgent = queryagent; | ||
479 | break; | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | return returnAgent; | ||
484 | } | ||
485 | |||
486 | public void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage) | ||
487 | { | ||
488 | CachedUserInfo userInfo = m_initialScene.CommsManager.UserProfileCacheService.GetUserDetails(fromUserId); | ||
489 | |||
490 | if (userInfo != null) | ||
491 | { | ||
492 | GridInstantMessage msg = new GridInstantMessage( | ||
493 | toUserClient.Scene, fromUserId, userInfo.UserProfile.Name, toUserClient.AgentId, | ||
494 | (byte)InstantMessageDialog.FriendshipOffered, offerMessage, false, Vector3.Zero); | ||
495 | |||
496 | FriendshipOffered(msg); | ||
497 | } | ||
498 | else | ||
499 | { | ||
500 | m_log.ErrorFormat("[FRIENDS]: No user found for id {0} in OfferFriendship()", fromUserId); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | #region FriendRequestHandling | ||
505 | |||
506 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) | ||
507 | { | ||
508 | // Friend Requests go by Instant Message.. using the dialog param | ||
509 | // https://wiki.secondlife.com/wiki/ImprovedInstantMessage | ||
510 | |||
511 | if (im.dialog == (byte)InstantMessageDialog.FriendshipOffered) // 38 | ||
512 | { | ||
513 | // fromAgentName is the *destination* name (the friend we offer friendship to) | ||
514 | ScenePresence initiator = GetAnyPresenceFromAgentID(new UUID(im.fromAgentID)); | ||
515 | im.fromAgentName = initiator != null ? initiator.Name : "(hippo)"; | ||
516 | |||
517 | FriendshipOffered(im); | ||
518 | } | ||
519 | else if (im.dialog == (byte)InstantMessageDialog.FriendshipAccepted) // 39 | ||
520 | { | ||
521 | FriendshipAccepted(client, im); | ||
522 | } | ||
523 | else if (im.dialog == (byte)InstantMessageDialog.FriendshipDeclined) // 40 | ||
524 | { | ||
525 | FriendshipDeclined(client, im); | ||
526 | } | ||
527 | } | ||
528 | |||
529 | /// <summary> | ||
530 | /// Invoked when a user offers a friendship. | ||
531 | /// </summary> | ||
532 | /// | ||
533 | /// <param name="im"></param> | ||
534 | /// <param name="client"></param> | ||
535 | private void FriendshipOffered(GridInstantMessage im) | ||
536 | { | ||
537 | // this is triggered by the initiating agent: | ||
538 | // A local agent offers friendship to some possibly remote friend. | ||
539 | // A IM is triggered, processed here and sent to the friend (possibly in a remote region). | ||
540 | |||
541 | m_log.DebugFormat("[FRIEND]: Offer(38) - From: {0}, FromName: {1} To: {2}, Session: {3}, Message: {4}, Offline {5}", | ||
542 | im.fromAgentID, im.fromAgentName, im.toAgentID, im.imSessionID, im.message, im.offline); | ||
543 | |||
544 | // 1.20 protocol sends an UUID in the message field, instead of the friendship offer text. | ||
545 | // For interoperability, we have to clear that | ||
546 | if (Util.isUUID(im.message)) im.message = ""; | ||
547 | |||
548 | // be sneeky and use the initiator-UUID as transactionID. This means we can be stateless. | ||
549 | // we have to look up the agent name on friendship-approval, though. | ||
550 | im.imSessionID = im.fromAgentID; | ||
551 | |||
552 | if (m_TransferModule != null) | ||
553 | { | ||
554 | // Send it to whoever is the destination. | ||
555 | // If new friend is local, it will send an IM to the viewer. | ||
556 | // If new friend is remote, it will cause a OnGridInstantMessage on the remote server | ||
557 | m_TransferModule.SendInstantMessage( | ||
558 | im, | ||
559 | delegate(bool success) | ||
560 | { | ||
561 | m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success); | ||
562 | } | ||
563 | ); | ||
564 | } | ||
565 | } | ||
566 | |||
567 | /// <summary> | ||
568 | /// Invoked when a user accepts a friendship offer. | ||
569 | /// </summary> | ||
570 | /// <param name="im"></param> | ||
571 | /// <param name="client"></param> | ||
572 | private void FriendshipAccepted(IClientAPI client, GridInstantMessage im) | ||
573 | { | ||
574 | m_log.DebugFormat("[FRIEND]: 39 - from client {0}, agent {2} {3}, imsession {4} to {5}: {6} (dialog {7})", | ||
575 | client.AgentId, im.fromAgentID, im.fromAgentName, im.imSessionID, im.toAgentID, im.message, im.dialog); | ||
576 | } | ||
577 | |||
578 | /// <summary> | ||
579 | /// Invoked when a user declines a friendship offer. | ||
580 | /// </summary> | ||
581 | /// May not currently be used - see OnDenyFriendRequest() instead | ||
582 | /// <param name="im"></param> | ||
583 | /// <param name="client"></param> | ||
584 | private void FriendshipDeclined(IClientAPI client, GridInstantMessage im) | ||
585 | { | ||
586 | UUID fromAgentID = new UUID(im.fromAgentID); | ||
587 | UUID toAgentID = new UUID(im.toAgentID); | ||
588 | |||
589 | // declining the friendship offer causes a type 40 IM being sent to the (possibly remote) initiator | ||
590 | // toAgentID is initiator, fromAgentID declined friendship | ||
591 | m_log.DebugFormat("[FRIEND]: 40 - from client {0}, agent {1} {2}, imsession {3} to {4}: {5} (dialog {6})", | ||
592 | client != null ? client.AgentId.ToString() : "<null>", | ||
593 | fromAgentID, im.fromAgentName, im.imSessionID, im.toAgentID, im.message, im.dialog); | ||
594 | |||
595 | // Send the decline to whoever is the destination. | ||
596 | GridInstantMessage msg | ||
597 | = new GridInstantMessage( | ||
598 | client.Scene, fromAgentID, client.Name, toAgentID, | ||
599 | im.dialog, im.message, im.offline != 0, im.Position); | ||
600 | |||
601 | // If new friend is local, it will send an IM to the viewer. | ||
602 | // If new friend is remote, it will cause a OnGridInstantMessage on the remote server | ||
603 | m_TransferModule.SendInstantMessage(msg, | ||
604 | delegate(bool success) { | ||
605 | m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success); | ||
606 | } | ||
607 | ); | ||
608 | } | ||
609 | |||
610 | private void OnGridInstantMessage(GridInstantMessage msg) | ||
611 | { | ||
612 | // This event won't be raised unless we have that agent, | ||
613 | // so we can depend on the above not trying to send | ||
614 | // via grid again | ||
615 | //m_log.DebugFormat("[FRIEND]: Got GridIM from {0}, to {1}, imSession {2}, message {3}, dialog {4}", | ||
616 | // msg.fromAgentID, msg.toAgentID, msg.imSessionID, msg.message, msg.dialog); | ||
617 | |||
618 | if (msg.dialog == (byte)InstantMessageDialog.FriendshipOffered || | ||
619 | msg.dialog == (byte)InstantMessageDialog.FriendshipAccepted || | ||
620 | msg.dialog == (byte)InstantMessageDialog.FriendshipDeclined) | ||
621 | { | ||
622 | // this should succeed as we *know* the root agent is here. | ||
623 | m_TransferModule.SendInstantMessage(msg, | ||
624 | delegate(bool success) { | ||
625 | //m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success); | ||
626 | } | ||
627 | ); | ||
628 | } | ||
629 | |||
630 | if (msg.dialog == (byte)InstantMessageDialog.FriendshipAccepted) | ||
631 | { | ||
632 | // for accept friendship, we have to do a bit more | ||
633 | ApproveFriendship(new UUID(msg.fromAgentID), new UUID(msg.toAgentID), msg.fromAgentName); | ||
634 | } | ||
635 | } | ||
636 | |||
637 | private void ApproveFriendship(UUID fromAgentID, UUID toAgentID, string fromName) | ||
638 | { | ||
639 | m_log.DebugFormat("[FRIEND]: Approve friendship from {0} (ID: {1}) to {2}", | ||
640 | fromAgentID, fromName, toAgentID); | ||
641 | |||
642 | // a new friend was added in the initiator's and friend's data, so the cache entries are wrong now. | ||
643 | lock (m_friendLists) | ||
644 | { | ||
645 | m_friendLists.Invalidate(fromAgentID.ToString()); | ||
646 | m_friendLists.Invalidate(toAgentID.ToString()); | ||
647 | } | ||
648 | |||
649 | // now send presence update and add a calling card for the new friend | ||
650 | |||
651 | ScenePresence initiator = GetAnyPresenceFromAgentID(toAgentID); | ||
652 | if (initiator == null) | ||
653 | { | ||
654 | // quite wrong. Shouldn't happen. | ||
655 | m_log.WarnFormat("[FRIEND]: Coudn't find initiator of friend request {0}", toAgentID); | ||
656 | return; | ||
657 | } | ||
658 | |||
659 | m_log.DebugFormat("[FRIEND]: Tell {0} that {1} is online", | ||
660 | initiator.Name, fromName); | ||
661 | // tell initiator that friend is online | ||
662 | initiator.ControllingClient.SendAgentOnline(new UUID[] { fromAgentID }); | ||
663 | |||
664 | // find the folder for the friend... | ||
665 | //InventoryFolderImpl folder = | ||
666 | // initiator.Scene.CommsManager.UserProfileCacheService.GetUserDetails(toAgentID).FindFolderForType((int)InventoryType.CallingCard); | ||
667 | IInventoryService invService = initiator.Scene.InventoryService; | ||
668 | InventoryFolderBase folder = invService.GetFolderForType(toAgentID, AssetType.CallingCard); | ||
669 | if (folder != null) | ||
670 | { | ||
671 | // ... and add the calling card | ||
672 | CreateCallingCard(initiator.ControllingClient, fromAgentID, folder.ID, fromName); | ||
673 | } | ||
674 | } | 55 | } |
675 | 56 | ||
676 | private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | 57 | public void AddRegion(Scene scene) |
677 | { | 58 | { |
678 | m_log.DebugFormat("[FRIEND]: Got approve friendship from {0} {1}, agentID {2}, tid {3}", | ||
679 | client.Name, client.AgentId, agentID, friendID); | ||
680 | |||
681 | // store the new friend persistently for both avatars | ||
682 | m_initialScene.StoreAddFriendship(friendID, agentID, (uint) FriendRights.CanSeeOnline); | ||
683 | |||
684 | // The cache entries aren't valid anymore either, as we just added a friend to both sides. | ||
685 | lock (m_friendLists) | ||
686 | { | ||
687 | m_friendLists.Invalidate(agentID.ToString()); | ||
688 | m_friendLists.Invalidate(friendID.ToString()); | ||
689 | } | ||
690 | |||
691 | // if it's a local friend, we don't have to do the lookup | ||
692 | ScenePresence friendPresence = GetAnyPresenceFromAgentID(friendID); | ||
693 | |||
694 | if (friendPresence != null) | ||
695 | { | ||
696 | m_log.Debug("[FRIEND]: Local agent detected."); | ||
697 | |||
698 | // create calling card | ||
699 | CreateCallingCard(client, friendID, callingCardFolders[0], friendPresence.Name); | ||
700 | |||
701 | // local message means OnGridInstantMessage won't be triggered, so do the work here. | ||
702 | friendPresence.ControllingClient.SendInstantMessage( | ||
703 | new GridInstantMessage(client.Scene, agentID, | ||
704 | client.Name, friendID, | ||
705 | (byte)InstantMessageDialog.FriendshipAccepted, | ||
706 | agentID.ToString(), false, Vector3.Zero)); | ||
707 | ApproveFriendship(agentID, friendID, client.Name); | ||
708 | } | ||
709 | else | ||
710 | { | ||
711 | m_log.Debug("[FRIEND]: Remote agent detected."); | ||
712 | |||
713 | // fetch the friend's name for the calling card. | ||
714 | CachedUserInfo info = m_initialScene.CommsManager.UserProfileCacheService.GetUserDetails(friendID); | ||
715 | |||
716 | // create calling card | ||
717 | CreateCallingCard(client, friendID, callingCardFolders[0], | ||
718 | info.UserProfile.FirstName + " " + info.UserProfile.SurName); | ||
719 | |||
720 | // Compose (remote) response to friend. | ||
721 | GridInstantMessage msg = new GridInstantMessage(client.Scene, agentID, client.Name, friendID, | ||
722 | (byte)InstantMessageDialog.FriendshipAccepted, | ||
723 | agentID.ToString(), false, Vector3.Zero); | ||
724 | if (m_TransferModule != null) | ||
725 | { | ||
726 | m_TransferModule.SendInstantMessage(msg, | ||
727 | delegate(bool success) { | ||
728 | m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success); | ||
729 | } | ||
730 | ); | ||
731 | } | ||
732 | } | ||
733 | |||
734 | // tell client that new friend is online | ||
735 | client.SendAgentOnline(new UUID[] { friendID }); | ||
736 | } | 59 | } |
737 | 60 | ||
738 | private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) | 61 | public void RegionLoaded(Scene scene) |
739 | { | 62 | { |
740 | m_log.DebugFormat("[FRIEND]: Got deny friendship from {0} {1}, agentID {2}, tid {3}", | ||
741 | client.Name, client.AgentId, agentID, friendID); | ||
742 | |||
743 | // Compose response to other agent. | ||
744 | GridInstantMessage msg = new GridInstantMessage(client.Scene, agentID, client.Name, friendID, | ||
745 | (byte)InstantMessageDialog.FriendshipDeclined, | ||
746 | agentID.ToString(), false, Vector3.Zero); | ||
747 | // send decline to initiator | ||
748 | if (m_TransferModule != null) | ||
749 | { | ||
750 | m_TransferModule.SendInstantMessage(msg, | ||
751 | delegate(bool success) { | ||
752 | m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success); | ||
753 | } | ||
754 | ); | ||
755 | } | ||
756 | } | 63 | } |
757 | 64 | ||
758 | private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) | 65 | public void RemoveRegion(Scene scene) |
759 | { | 66 | { |
760 | // client.AgentId == agentID! | ||
761 | |||
762 | // this removes the friends from the stored friendlists. After the next login, they will be gone... | ||
763 | m_initialScene.StoreRemoveFriendship(agentID, exfriendID); | ||
764 | |||
765 | // ... now tell the two involved clients that they aren't friends anymore. | ||
766 | |||
767 | // I don't know why we have to tell <agent>, as this was caused by her, but that's how it works in SL... | ||
768 | client.SendTerminateFriend(exfriendID); | ||
769 | |||
770 | // now send the friend, if online | ||
771 | ScenePresence presence = GetAnyPresenceFromAgentID(exfriendID); | ||
772 | if (presence != null) | ||
773 | { | ||
774 | m_log.DebugFormat("[FRIEND]: Sending terminate friend {0} to agent {1}", agentID, exfriendID); | ||
775 | presence.ControllingClient.SendTerminateFriend(agentID); | ||
776 | } | ||
777 | else | ||
778 | { | ||
779 | // retry 3 times, in case the agent TPed from the last known region... | ||
780 | for (int retry = 0; retry < 3; ++retry) | ||
781 | { | ||
782 | // wasn't sent, so ex-friend wasn't around on this region-server. Fetch info and try to send | ||
783 | UserAgentData data = m_initialScene.CommsManager.UserService.GetAgentByUUID(exfriendID); | ||
784 | |||
785 | if (null == data) | ||
786 | break; | ||
787 | |||
788 | if (!data.AgentOnline) | ||
789 | { | ||
790 | m_log.DebugFormat("[FRIEND]: {0} is offline, so not sending TerminateFriend", exfriendID); | ||
791 | break; // if ex-friend isn't online, we don't need to send | ||
792 | } | ||
793 | |||
794 | m_log.DebugFormat("[FRIEND]: Sending remote terminate friend {0} to agent {1}@{2}", | ||
795 | agentID, exfriendID, data.Handle); | ||
796 | |||
797 | // try to send to foreign region, retry if it fails (friend TPed away, for example) | ||
798 | if (TriggerTerminateFriend(data.Handle, exfriendID, agentID)) break; | ||
799 | } | ||
800 | } | ||
801 | |||
802 | // clean up cache: FriendList is wrong now... | ||
803 | lock (m_friendLists) | ||
804 | { | ||
805 | m_friendLists.Invalidate(agentID.ToString()); | ||
806 | m_friendLists.Invalidate(exfriendID.ToString()); | ||
807 | } | ||
808 | } | 67 | } |
809 | 68 | ||
810 | #endregion | 69 | public void Close() |
811 | |||
812 | #region CallingCards | ||
813 | |||
814 | private void OnOfferCallingCard(IClientAPI client, UUID destID, UUID transactionID) | ||
815 | { | ||
816 | m_log.DebugFormat("[CALLING CARD]: got offer from {0} for {1}, transaction {2}", | ||
817 | client.AgentId, destID, transactionID); | ||
818 | // This might be slightly wrong. On a multi-region server, we might get the child-agent instead of the root-agent | ||
819 | // (or the root instead of the child) | ||
820 | ScenePresence destAgent = GetAnyPresenceFromAgentID(destID); | ||
821 | if (destAgent == null) | ||
822 | { | ||
823 | client.SendAlertMessage("The person you have offered a card to can't be found anymore."); | ||
824 | return; | ||
825 | } | ||
826 | |||
827 | lock (m_pendingCallingcardRequests) | ||
828 | { | ||
829 | m_pendingCallingcardRequests[transactionID] = client.AgentId; | ||
830 | } | ||
831 | // inform the destination agent about the offer | ||
832 | destAgent.ControllingClient.SendOfferCallingCard(client.AgentId, transactionID); | ||
833 | } | ||
834 | |||
835 | private void CreateCallingCard(IClientAPI client, UUID creator, UUID folder, string name) | ||
836 | { | ||
837 | InventoryItemBase item = new InventoryItemBase(); | ||
838 | item.AssetID = UUID.Zero; | ||
839 | item.AssetType = (int)AssetType.CallingCard; | ||
840 | item.BasePermissions = (uint)PermissionMask.Copy; | ||
841 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
842 | item.CreatorId = creator.ToString(); | ||
843 | item.CurrentPermissions = item.BasePermissions; | ||
844 | item.Description = ""; | ||
845 | item.EveryOnePermissions = (uint)PermissionMask.None; | ||
846 | item.Flags = 0; | ||
847 | item.Folder = folder; | ||
848 | item.GroupID = UUID.Zero; | ||
849 | item.GroupOwned = false; | ||
850 | item.ID = UUID.Random(); | ||
851 | item.InvType = (int)InventoryType.CallingCard; | ||
852 | item.Name = name; | ||
853 | item.NextPermissions = item.EveryOnePermissions; | ||
854 | item.Owner = client.AgentId; | ||
855 | item.SalePrice = 10; | ||
856 | item.SaleType = (byte)SaleType.Not; | ||
857 | ((Scene)client.Scene).AddInventoryItem(client, item); | ||
858 | } | ||
859 | |||
860 | private void OnAcceptCallingCard(IClientAPI client, UUID transactionID, UUID folderID) | ||
861 | { | ||
862 | m_log.DebugFormat("[CALLING CARD]: User {0} ({1} {2}) accepted tid {3}, folder {4}", | ||
863 | client.AgentId, | ||
864 | client.FirstName, client.LastName, | ||
865 | transactionID, folderID); | ||
866 | UUID destID; | ||
867 | lock (m_pendingCallingcardRequests) | ||
868 | { | ||
869 | if (!m_pendingCallingcardRequests.TryGetValue(transactionID, out destID)) | ||
870 | { | ||
871 | m_log.WarnFormat("[CALLING CARD]: Got a AcceptCallingCard from {0} without an offer before.", | ||
872 | client.Name); | ||
873 | return; | ||
874 | } | ||
875 | // else found pending calling card request with that transaction. | ||
876 | m_pendingCallingcardRequests.Remove(transactionID); | ||
877 | } | ||
878 | |||
879 | |||
880 | ScenePresence destAgent = GetAnyPresenceFromAgentID(destID); | ||
881 | // inform sender of the card that destination declined the offer | ||
882 | if (destAgent != null) destAgent.ControllingClient.SendAcceptCallingCard(transactionID); | ||
883 | |||
884 | // put a calling card into the inventory of receiver | ||
885 | CreateCallingCard(client, destID, folderID, destAgent.Name); | ||
886 | } | ||
887 | |||
888 | private void OnDeclineCallingCard(IClientAPI client, UUID transactionID) | ||
889 | { | 70 | { |
890 | m_log.DebugFormat("[CALLING CARD]: User {0} (ID:{1}) declined card, tid {2}", | ||
891 | client.Name, client.AgentId, transactionID); | ||
892 | UUID destID; | ||
893 | lock (m_pendingCallingcardRequests) | ||
894 | { | ||
895 | if (!m_pendingCallingcardRequests.TryGetValue(transactionID, out destID)) | ||
896 | { | ||
897 | m_log.WarnFormat("[CALLING CARD]: Got a AcceptCallingCard from {0} without an offer before.", | ||
898 | client.Name); | ||
899 | return; | ||
900 | } | ||
901 | // else found pending calling card request with that transaction. | ||
902 | m_pendingCallingcardRequests.Remove(transactionID); | ||
903 | } | ||
904 | |||
905 | ScenePresence destAgent = GetAnyPresenceFromAgentID(destID); | ||
906 | // inform sender of the card that destination declined the offer | ||
907 | if (destAgent != null) destAgent.ControllingClient.SendDeclineCallingCard(transactionID); | ||
908 | } | 71 | } |
909 | 72 | ||
910 | /// <summary> | 73 | public string Name |
911 | /// Send presence information about a client to other clients in both this region and others. | ||
912 | /// </summary> | ||
913 | /// <param name="client"></param> | ||
914 | /// <param name="friendList"></param> | ||
915 | /// <param name="iAmOnline"></param> | ||
916 | private void SendPresenceState(IClientAPI client, List<FriendListItem> friendList, bool iAmOnline) | ||
917 | { | 74 | { |
918 | //m_log.DebugFormat("[FRIEND]: {0} logged {1}; sending presence updates", client.Name, iAmOnline ? "in" : "out"); | 75 | get { return "FriendsModule"; } |
919 | |||
920 | if (friendList == null || friendList.Count == 0) | ||
921 | { | ||
922 | //m_log.DebugFormat("[FRIEND]: {0} doesn't have friends.", client.Name); | ||
923 | return; // nothing we can do if she doesn't have friends... | ||
924 | } | ||
925 | |||
926 | // collect sets of friendIDs; to send to (online and offline), and to receive from | ||
927 | // TODO: If we ever switch to .NET >= 3, replace those Lists with HashSets. | ||
928 | // I can't believe that we have Dictionaries, but no Sets, considering Java introduced them years ago... | ||
929 | List<UUID> friendIDsToSendTo = new List<UUID>(); | ||
930 | List<UUID> candidateFriendIDsToReceive = new List<UUID>(); | ||
931 | |||
932 | foreach (FriendListItem item in friendList) | ||
933 | { | ||
934 | if (((item.FriendListOwnerPerms | item.FriendPerms) & (uint)FriendRights.CanSeeOnline) != 0) | ||
935 | { | ||
936 | // friend is allowed to see my presence => add | ||
937 | if ((item.FriendListOwnerPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||
938 | friendIDsToSendTo.Add(item.Friend); | ||
939 | |||
940 | if ((item.FriendPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||
941 | candidateFriendIDsToReceive.Add(item.Friend); | ||
942 | } | ||
943 | } | ||
944 | |||
945 | // we now have a list of "interesting" friends (which we have to find out on-/offline state for), | ||
946 | // friends we want to send our online state to (if *they* are online, too), and | ||
947 | // friends we want to receive online state for (currently unknown whether online or not) | ||
948 | |||
949 | // as this processing might take some time and friends might TP away, we try up to three times to | ||
950 | // reach them. Most of the time, we *will* reach them, and this loop won't loop | ||
951 | int retry = 0; | ||
952 | do | ||
953 | { | ||
954 | // build a list of friends to look up region-information and on-/offline-state for | ||
955 | List<UUID> friendIDsToLookup = new List<UUID>(friendIDsToSendTo); | ||
956 | foreach (UUID uuid in candidateFriendIDsToReceive) | ||
957 | { | ||
958 | if (!friendIDsToLookup.Contains(uuid)) friendIDsToLookup.Add(uuid); | ||
959 | } | ||
960 | |||
961 | m_log.DebugFormat( | ||
962 | "[FRIEND]: {0} to lookup, {1} to send to, {2} candidates to receive from for agent {3}", | ||
963 | friendIDsToLookup.Count, friendIDsToSendTo.Count, candidateFriendIDsToReceive.Count, client.Name); | ||
964 | |||
965 | // we have to fetch FriendRegionInfos, as the (cached) FriendListItems don't | ||
966 | // necessarily contain the correct online state... | ||
967 | Dictionary<UUID, FriendRegionInfo> friendRegions = m_initialScene.GetFriendRegionInfos(friendIDsToLookup); | ||
968 | m_log.DebugFormat( | ||
969 | "[FRIEND]: Found {0} regionInfos for {1} friends of {2}", | ||
970 | friendRegions.Count, friendIDsToLookup.Count, client.Name); | ||
971 | |||
972 | // argument for SendAgentOn/Offline; we shouldn't generate that repeatedly within loops. | ||
973 | UUID[] agentArr = new UUID[] { client.AgentId }; | ||
974 | |||
975 | // first, send to friend presence state to me, if I'm online... | ||
976 | if (iAmOnline) | ||
977 | { | ||
978 | List<UUID> friendIDsToReceive = new List<UUID>(); | ||
979 | |||
980 | for (int i = candidateFriendIDsToReceive.Count - 1; i >= 0; --i) | ||
981 | { | ||
982 | UUID uuid = candidateFriendIDsToReceive[i]; | ||
983 | FriendRegionInfo info; | ||
984 | if (friendRegions.TryGetValue(uuid, out info) && info != null && info.isOnline) | ||
985 | { | ||
986 | friendIDsToReceive.Add(uuid); | ||
987 | } | ||
988 | } | ||
989 | |||
990 | m_log.DebugFormat( | ||
991 | "[FRIEND]: Sending {0} online friends to {1}", friendIDsToReceive.Count, client.Name); | ||
992 | |||
993 | if (friendIDsToReceive.Count > 0) | ||
994 | client.SendAgentOnline(friendIDsToReceive.ToArray()); | ||
995 | |||
996 | // clear them for a possible second iteration; we don't have to repeat this | ||
997 | candidateFriendIDsToReceive.Clear(); | ||
998 | } | ||
999 | |||
1000 | // now, send my presence state to my friends | ||
1001 | for (int i = friendIDsToSendTo.Count - 1; i >= 0; --i) | ||
1002 | { | ||
1003 | UUID uuid = friendIDsToSendTo[i]; | ||
1004 | FriendRegionInfo info; | ||
1005 | if (friendRegions.TryGetValue(uuid, out info) && info != null && info.isOnline) | ||
1006 | { | ||
1007 | // any client is good enough, root or child... | ||
1008 | ScenePresence agent = GetAnyPresenceFromAgentID(uuid); | ||
1009 | if (agent != null) | ||
1010 | { | ||
1011 | //m_log.DebugFormat("[FRIEND]: Found local agent {0}", agent.Name); | ||
1012 | |||
1013 | // friend is online and on this server... | ||
1014 | if (iAmOnline) agent.ControllingClient.SendAgentOnline(agentArr); | ||
1015 | else agent.ControllingClient.SendAgentOffline(agentArr); | ||
1016 | |||
1017 | // done, remove it | ||
1018 | friendIDsToSendTo.RemoveAt(i); | ||
1019 | } | ||
1020 | } | ||
1021 | else | ||
1022 | { | ||
1023 | //m_log.DebugFormat("[FRIEND]: Friend {0} ({1}) is offline; not sending.", uuid, i); | ||
1024 | |||
1025 | // friend is offline => no need to try sending | ||
1026 | friendIDsToSendTo.RemoveAt(i); | ||
1027 | } | ||
1028 | } | ||
1029 | |||
1030 | m_log.DebugFormat("[FRIEND]: Have {0} friends to contact via inter-region comms.", friendIDsToSendTo.Count); | ||
1031 | |||
1032 | // we now have all the friends left that are online (we think), but not on this region-server | ||
1033 | if (friendIDsToSendTo.Count > 0) | ||
1034 | { | ||
1035 | // sort them into regions | ||
1036 | Dictionary<ulong, List<UUID>> friendsInRegion = new Dictionary<ulong,List<UUID>>(); | ||
1037 | foreach (UUID uuid in friendIDsToSendTo) | ||
1038 | { | ||
1039 | ulong handle = friendRegions[uuid].regionHandle; // this can't fail as we filtered above already | ||
1040 | List<UUID> friends; | ||
1041 | if (!friendsInRegion.TryGetValue(handle, out friends)) | ||
1042 | { | ||
1043 | friends = new List<UUID>(); | ||
1044 | friendsInRegion[handle] = friends; | ||
1045 | } | ||
1046 | friends.Add(uuid); | ||
1047 | } | ||
1048 | m_log.DebugFormat("[FRIEND]: Found {0} regions to send to.", friendRegions.Count); | ||
1049 | |||
1050 | // clear uuids list and collect missed friends in it for the next retry | ||
1051 | friendIDsToSendTo.Clear(); | ||
1052 | |||
1053 | // send bulk updates to the region | ||
1054 | foreach (KeyValuePair<ulong, List<UUID>> pair in friendsInRegion) | ||
1055 | { | ||
1056 | //m_log.DebugFormat("[FRIEND]: Inform {0} friends in region {1} that user {2} is {3}line", | ||
1057 | // pair.Value.Count, pair.Key, client.Name, iAmOnline ? "on" : "off"); | ||
1058 | |||
1059 | friendIDsToSendTo.AddRange(InformFriendsInOtherRegion(client.AgentId, pair.Key, pair.Value, iAmOnline)); | ||
1060 | } | ||
1061 | } | ||
1062 | // now we have in friendIDsToSendTo only the agents left that TPed away while we tried to contact them. | ||
1063 | // In most cases, it will be empty, and it won't loop here. But sometimes, we have to work harder and try again... | ||
1064 | } | ||
1065 | while (++retry < 3 && friendIDsToSendTo.Count > 0); | ||
1066 | } | 76 | } |
1067 | 77 | ||
1068 | private void OnEconomyDataRequest(UUID agentID) | 78 | public Type ReplaceableInterface |
1069 | { | 79 | { |
1070 | // KLUDGE: This is the only way I found to get a message (only) after login was completed and the | 80 | get { return null; } |
1071 | // client is connected enough to receive UDP packets). | ||
1072 | // This packet seems to be sent only once, just after connection was established to the first | ||
1073 | // region after login. | ||
1074 | // We use it here to trigger a presence update; the old update-on-login was never be heard by | ||
1075 | // the freshly logged in viewer, as it wasn't connected to the region at that time. | ||
1076 | // TODO: Feel free to replace this by a better solution if you find one. | ||
1077 | |||
1078 | // get the agent. This should work every time, as we just got a packet from it | ||
1079 | //ScenePresence agent = GetRootPresenceFromAgentID(agentID); | ||
1080 | // KLUDGE 2: As this is sent quite early, the avatar isn't here as root agent yet. So, we have to cheat a bit | ||
1081 | ScenePresence agent = GetAnyPresenceFromAgentID(agentID); | ||
1082 | |||
1083 | // just to be paranoid... | ||
1084 | if (agent == null) | ||
1085 | { | ||
1086 | m_log.ErrorFormat("[FRIEND]: Got a packet from agent {0} who can't be found anymore!?", agentID); | ||
1087 | return; | ||
1088 | } | ||
1089 | |||
1090 | List<FriendListItem> fl; | ||
1091 | lock (m_friendLists) | ||
1092 | { | ||
1093 | fl = (List<FriendListItem>)m_friendLists.Get(agent.ControllingClient.AgentId.ToString(), | ||
1094 | m_initialScene.GetFriendList); | ||
1095 | } | ||
1096 | |||
1097 | // tell everyone that we are online | ||
1098 | SendPresenceState(agent.ControllingClient, fl, true); | ||
1099 | } | 81 | } |
1100 | 82 | ||
1101 | private void OnLogout(IClientAPI remoteClient) | 83 | public void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, |
84 | string offerMessage) | ||
1102 | { | 85 | { |
1103 | List<FriendListItem> fl; | ||
1104 | lock (m_friendLists) | ||
1105 | { | ||
1106 | fl = (List<FriendListItem>)m_friendLists.Get(remoteClient.AgentId.ToString(), | ||
1107 | m_initialScene.GetFriendList); | ||
1108 | } | ||
1109 | |||
1110 | // tell everyone that we are offline | ||
1111 | SendPresenceState(remoteClient, fl, false); | ||
1112 | } | ||
1113 | private void GrantUserFriendRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) | ||
1114 | { | ||
1115 | ((Scene)remoteClient.Scene).CommsManager.UpdateUserFriendPerms(requester, target, (uint)rights); | ||
1116 | } | 86 | } |
1117 | 87 | ||
1118 | public List<FriendListItem> GetUserFriends(UUID agentID) | 88 | public List<FriendListItem> GetUserFriends(UUID agentID) |
1119 | { | 89 | { |
1120 | List<FriendListItem> fl; | 90 | return null; |
1121 | lock (m_friendLists) | ||
1122 | { | ||
1123 | fl = (List<FriendListItem>)m_friendLists.Get(agentID.ToString(), | ||
1124 | m_initialScene.GetFriendList); | ||
1125 | } | ||
1126 | |||
1127 | return fl; | ||
1128 | } | 91 | } |
1129 | } | 92 | } |
1130 | #endregion | ||
1131 | } | 93 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index 9a68749..ab141eb 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs | |||
@@ -24,6 +24,7 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | ||
27 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
28 | using System.Reflection; | 29 | using System.Reflection; |
29 | using log4net; | 30 | using log4net; |
@@ -36,9 +37,10 @@ using OpenSim.Region.Framework.Scenes; | |||
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 38 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
38 | { | 39 | { |
39 | public class InstantMessageModule : IRegionModule | 40 | public class InstantMessageModule : ISharedRegionModule |
40 | { | 41 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | private static readonly ILog m_log = LogManager.GetLogger( |
43 | MethodBase.GetCurrentMethod().DeclaringType); | ||
42 | 44 | ||
43 | /// <value> | 45 | /// <value> |
44 | /// Is this module enabled? | 46 | /// Is this module enabled? |
@@ -51,7 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
51 | 53 | ||
52 | private IMessageTransferModule m_TransferModule = null; | 54 | private IMessageTransferModule m_TransferModule = null; |
53 | 55 | ||
54 | public void Initialise(Scene scene, IConfigSource config) | 56 | public void Initialise(IConfigSource config) |
55 | { | 57 | { |
56 | if (config.Configs["Messaging"] != null) | 58 | if (config.Configs["Messaging"] != null) |
57 | { | 59 | { |
@@ -62,6 +64,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
62 | } | 64 | } |
63 | 65 | ||
64 | m_enabled = true; | 66 | m_enabled = true; |
67 | } | ||
68 | |||
69 | public void AddRegion(Scene scene) | ||
70 | { | ||
71 | if (!m_enabled) | ||
72 | return; | ||
65 | 73 | ||
66 | lock (m_scenes) | 74 | lock (m_scenes) |
67 | { | 75 | { |
@@ -74,6 +82,39 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
74 | } | 82 | } |
75 | } | 83 | } |
76 | 84 | ||
85 | public void RegionLoaded(Scene scene) | ||
86 | { | ||
87 | if (!m_enabled) | ||
88 | return; | ||
89 | |||
90 | if (m_TransferModule == null) | ||
91 | { | ||
92 | m_TransferModule = | ||
93 | scene.RequestModuleInterface<IMessageTransferModule>(); | ||
94 | |||
95 | if (m_TransferModule == null) | ||
96 | { | ||
97 | m_log.Error("[INSTANT MESSAGE]: No message transfer module, IM will not work!"); | ||
98 | scene.EventManager.OnClientConnect -= OnClientConnect; | ||
99 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | ||
100 | |||
101 | m_scenes.Clear(); | ||
102 | m_enabled = false; | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | public void RemoveRegion(Scene scene) | ||
108 | { | ||
109 | if (!m_enabled) | ||
110 | return; | ||
111 | |||
112 | lock (m_scenes) | ||
113 | { | ||
114 | m_scenes.Remove(scene); | ||
115 | } | ||
116 | } | ||
117 | |||
77 | void OnClientConnect(IClientCore client) | 118 | void OnClientConnect(IClientCore client) |
78 | { | 119 | { |
79 | IClientIM clientIM; | 120 | IClientIM clientIM; |
@@ -85,15 +126,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
85 | 126 | ||
86 | public void PostInitialise() | 127 | public void PostInitialise() |
87 | { | 128 | { |
88 | if (!m_enabled) | ||
89 | return; | ||
90 | |||
91 | m_TransferModule = | ||
92 | m_scenes[0].RequestModuleInterface<IMessageTransferModule>(); | ||
93 | |||
94 | if (m_TransferModule == null) | ||
95 | m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ | ||
96 | "IM will not work!"); | ||
97 | } | 129 | } |
98 | 130 | ||
99 | public void Close() | 131 | public void Close() |
@@ -105,9 +137,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
105 | get { return "InstantMessageModule"; } | 137 | get { return "InstantMessageModule"; } |
106 | } | 138 | } |
107 | 139 | ||
108 | public bool IsSharedModule | 140 | public Type ReplaceableInterface |
109 | { | 141 | { |
110 | get { return true; } | 142 | get { return null; } |
111 | } | 143 | } |
112 | 144 | ||
113 | #endregion | 145 | #endregion |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index e5159b3..2d4b421 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | |||
@@ -40,18 +40,17 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; | |||
40 | 40 | ||
41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
42 | { | 42 | { |
43 | public class MessageTransferModule : IRegionModule, IMessageTransferModule | 43 | public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule |
44 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | // private bool m_Enabled = false; | 47 | private bool m_Enabled = false; |
48 | protected bool m_Gridmode = false; | ||
49 | protected List<Scene> m_Scenes = new List<Scene>(); | 48 | protected List<Scene> m_Scenes = new List<Scene>(); |
50 | protected Dictionary<UUID, ulong> m_UserRegionMap = new Dictionary<UUID, ulong>(); | 49 | protected Dictionary<UUID, ulong> m_UserRegionMap = new Dictionary<UUID, ulong>(); |
51 | 50 | ||
52 | public event UndeliveredMessage OnUndeliveredMessage; | 51 | public event UndeliveredMessage OnUndeliveredMessage; |
53 | 52 | ||
54 | public virtual void Initialise(Scene scene, IConfigSource config) | 53 | public virtual void Initialise(IConfigSource config) |
55 | { | 54 | { |
56 | IConfig cnf = config.Configs["Messaging"]; | 55 | IConfig cnf = config.Configs["Messaging"]; |
57 | if (cnf != null && cnf.GetString( | 56 | if (cnf != null && cnf.GetString( |
@@ -62,20 +61,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
62 | return; | 61 | return; |
63 | } | 62 | } |
64 | 63 | ||
65 | cnf = config.Configs["Startup"]; | 64 | m_Enabled = true; |
66 | if (cnf != null) | 65 | } |
67 | m_Gridmode = cnf.GetBoolean("gridmode", false); | ||
68 | 66 | ||
69 | // m_Enabled = true; | 67 | public virtual void AddRegion(Scene scene) |
68 | { | ||
69 | if (!m_Enabled) | ||
70 | return; | ||
70 | 71 | ||
71 | lock (m_Scenes) | 72 | lock (m_Scenes) |
72 | { | 73 | { |
73 | if (m_Scenes.Count == 0) | ||
74 | { | ||
75 | MainServer.Instance.AddXmlRPCHandler( | ||
76 | "grid_instant_message", processXMLRPCGridInstantMessage); | ||
77 | } | ||
78 | |||
79 | m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); | 74 | m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); |
80 | scene.RegisterModuleInterface<IMessageTransferModule>(this); | 75 | scene.RegisterModuleInterface<IMessageTransferModule>(this); |
81 | m_Scenes.Add(scene); | 76 | m_Scenes.Add(scene); |
@@ -84,6 +79,26 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
84 | 79 | ||
85 | public virtual void PostInitialise() | 80 | public virtual void PostInitialise() |
86 | { | 81 | { |
82 | if (!m_Enabled) | ||
83 | return; | ||
84 | |||
85 | MainServer.Instance.AddXmlRPCHandler( | ||
86 | "grid_instant_message", processXMLRPCGridInstantMessage); | ||
87 | } | ||
88 | |||
89 | public virtual void RegionLoaded(Scene scene) | ||
90 | { | ||
91 | } | ||
92 | |||
93 | public virtual void RemoveRegion(Scene scene) | ||
94 | { | ||
95 | if (!m_Enabled) | ||
96 | return; | ||
97 | |||
98 | lock(m_Scenes) | ||
99 | { | ||
100 | m_Scenes.Remove(scene); | ||
101 | } | ||
87 | } | 102 | } |
88 | 103 | ||
89 | public virtual void Close() | 104 | public virtual void Close() |
@@ -95,9 +110,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
95 | get { return "MessageTransferModule"; } | 110 | get { return "MessageTransferModule"; } |
96 | } | 111 | } |
97 | 112 | ||
98 | public virtual bool IsSharedModule | 113 | public virtual Type ReplaceableInterface |
99 | { | 114 | { |
100 | get { return true; } | 115 | get { return null; } |
101 | } | 116 | } |
102 | 117 | ||
103 | public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) | 118 | public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) |
@@ -148,15 +163,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
148 | } | 163 | } |
149 | } | 164 | } |
150 | 165 | ||
151 | if (m_Gridmode) | 166 | SendGridInstantMessageViaXMLRPC(im, result); |
152 | { | ||
153 | //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering via grid"); | ||
154 | // Still here, try send via Grid | ||
155 | SendGridInstantMessageViaXMLRPC(im, result); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | HandleUndeliveredMessage(im, result); | ||
160 | 167 | ||
161 | return; | 168 | return; |
162 | } | 169 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs index 2d4a635..24cbaeb 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs | |||
@@ -37,9 +37,9 @@ using OpenSim.Framework.Client; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | 39 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.MuteList | 40 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
41 | { | 41 | { |
42 | public class MuteListModule : IRegionModule | 42 | public class MuteListModule : ISharedRegionModule |
43 | { | 43 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
@@ -47,11 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList | |||
47 | private List<Scene> m_SceneList = new List<Scene>(); | 47 | private List<Scene> m_SceneList = new List<Scene>(); |
48 | private string m_RestURL = String.Empty; | 48 | private string m_RestURL = String.Empty; |
49 | 49 | ||
50 | public void Initialise(Scene scene, IConfigSource config) | 50 | public void Initialise(IConfigSource config) |
51 | { | 51 | { |
52 | if (!enabled) | ||
53 | return; | ||
54 | |||
55 | IConfig cnf = config.Configs["Messaging"]; | 52 | IConfig cnf = config.Configs["Messaging"]; |
56 | if (cnf == null) | 53 | if (cnf == null) |
57 | { | 54 | { |
@@ -59,39 +56,53 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList | |||
59 | return; | 56 | return; |
60 | } | 57 | } |
61 | 58 | ||
62 | if (cnf != null && cnf.GetString( | 59 | if (cnf != null && cnf.GetString("MuteListModule", "None") != |
63 | "MuteListModule", "None") != | ||
64 | "MuteListModule") | 60 | "MuteListModule") |
65 | { | 61 | { |
66 | enabled = false; | 62 | enabled = false; |
67 | return; | 63 | return; |
68 | } | 64 | } |
69 | 65 | ||
66 | m_RestURL = cnf.GetString("MuteListURL", ""); | ||
67 | if (m_RestURL == "") | ||
68 | { | ||
69 | m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); | ||
70 | enabled = false; | ||
71 | return; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public void AddRegion(Scene scene) | ||
76 | { | ||
77 | if (!enabled) | ||
78 | return; | ||
79 | |||
70 | lock (m_SceneList) | 80 | lock (m_SceneList) |
71 | { | 81 | { |
72 | if (m_SceneList.Count == 0) | 82 | m_SceneList.Add(scene); |
73 | { | ||
74 | m_RestURL = cnf.GetString("MuteListURL", ""); | ||
75 | if (m_RestURL == "") | ||
76 | { | ||
77 | m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); | ||
78 | enabled = false; | ||
79 | return; | ||
80 | } | ||
81 | } | ||
82 | if (!m_SceneList.Contains(scene)) | ||
83 | m_SceneList.Add(scene); | ||
84 | 83 | ||
85 | scene.EventManager.OnNewClient += OnNewClient; | 84 | scene.EventManager.OnNewClient += OnNewClient; |
86 | } | 85 | } |
87 | } | 86 | } |
88 | 87 | ||
89 | public void PostInitialise() | 88 | public void RegionLoaded(Scene scene) |
89 | { | ||
90 | } | ||
91 | |||
92 | public void RemoveRegion(Scene scene) | ||
90 | { | 93 | { |
91 | if (!enabled) | 94 | if (!enabled) |
92 | return; | 95 | return; |
93 | 96 | ||
94 | if (m_SceneList.Count == 0) | 97 | lock (m_SceneList) |
98 | { | ||
99 | m_SceneList.Remove(scene); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | public void PostInitialise() | ||
104 | { | ||
105 | if (!enabled) | ||
95 | return; | 106 | return; |
96 | 107 | ||
97 | m_log.Debug("[MUTE LIST] Mute list enabled"); | 108 | m_log.Debug("[MUTE LIST] Mute list enabled"); |
@@ -102,26 +113,15 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList | |||
102 | get { return "MuteListModule"; } | 113 | get { return "MuteListModule"; } |
103 | } | 114 | } |
104 | 115 | ||
105 | public bool IsSharedModule | 116 | public Type ReplaceableInterface |
106 | { | 117 | { |
107 | get { return true; } | 118 | get { return null; } |
108 | } | 119 | } |
109 | 120 | ||
110 | public void Close() | 121 | public void Close() |
111 | { | 122 | { |
112 | } | 123 | } |
113 | 124 | ||
114 | // private IClientAPI FindClient(UUID agentID) | ||
115 | // { | ||
116 | // foreach (Scene s in m_SceneList) | ||
117 | // { | ||
118 | // ScenePresence presence = s.GetScenePresence(agentID); | ||
119 | // if (presence != null && !presence.IsChildAgent) | ||
120 | // return presence.ControllingClient; | ||
121 | // } | ||
122 | // return null; | ||
123 | // } | ||
124 | |||
125 | private void OnNewClient(IClientAPI client) | 125 | private void OnNewClient(IClientAPI client) |
126 | { | 126 | { |
127 | client.OnMuteListRequest += OnMuteListRequest; | 127 | client.OnMuteListRequest += OnMuteListRequest; |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 1614b70..a835c52 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | |||
@@ -40,78 +40,88 @@ using OpenSim.Region.Framework.Scenes; | |||
40 | 40 | ||
41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
42 | { | 42 | { |
43 | public class OfflineMessageModule : IRegionModule | 43 | public class OfflineMessageModule : ISharedRegionModule |
44 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private bool enabled = true; | 47 | private bool enabled = true; |
48 | private List<Scene> m_SceneList = new List<Scene>(); | 48 | private List<Scene> m_SceneList = new List<Scene>(); |
49 | private string m_RestURL = String.Empty; | 49 | private string m_RestURL = String.Empty; |
50 | IMessageTransferModule m_TransferModule = null; | ||
50 | 51 | ||
51 | public void Initialise(Scene scene, IConfigSource config) | 52 | public void Initialise(IConfigSource config) |
52 | { | 53 | { |
53 | if (!enabled) | ||
54 | return; | ||
55 | |||
56 | IConfig cnf = config.Configs["Messaging"]; | 54 | IConfig cnf = config.Configs["Messaging"]; |
57 | if (cnf == null) | 55 | if (cnf == null) |
58 | { | 56 | { |
59 | enabled = false; | 57 | enabled = false; |
60 | return; | 58 | return; |
61 | } | 59 | } |
62 | if (cnf != null && cnf.GetString( | 60 | if (cnf != null && cnf.GetString("OfflineMessageModule", "None") != |
63 | "OfflineMessageModule", "None") != | ||
64 | "OfflineMessageModule") | 61 | "OfflineMessageModule") |
65 | { | 62 | { |
66 | enabled = false; | 63 | enabled = false; |
67 | return; | 64 | return; |
68 | } | 65 | } |
69 | 66 | ||
67 | m_RestURL = cnf.GetString("OfflineMessageURL", ""); | ||
68 | if (m_RestURL == "") | ||
69 | { | ||
70 | m_log.Error("[OFFLINE MESSAGING] Module was enabled, but no URL is given, disabling"); | ||
71 | enabled = false; | ||
72 | return; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | public void AddRegion(Scene scene) | ||
77 | { | ||
78 | if (!enabled) | ||
79 | return; | ||
80 | |||
70 | lock (m_SceneList) | 81 | lock (m_SceneList) |
71 | { | 82 | { |
72 | if (m_SceneList.Count == 0) | 83 | m_SceneList.Add(scene); |
73 | { | ||
74 | m_RestURL = cnf.GetString("OfflineMessageURL", ""); | ||
75 | if (m_RestURL == "") | ||
76 | { | ||
77 | m_log.Error("[OFFLINE MESSAGING] Module was enabled, but no URL is given, disabling"); | ||
78 | enabled = false; | ||
79 | return; | ||
80 | } | ||
81 | } | ||
82 | if (!m_SceneList.Contains(scene)) | ||
83 | m_SceneList.Add(scene); | ||
84 | 84 | ||
85 | scene.EventManager.OnNewClient += OnNewClient; | 85 | scene.EventManager.OnNewClient += OnNewClient; |
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | public void PostInitialise() | 89 | public void RegionLoaded(Scene scene) |
90 | { | 90 | { |
91 | if (!enabled) | 91 | if (!enabled) |
92 | return; | 92 | return; |
93 | 93 | ||
94 | if (m_SceneList.Count == 0) | 94 | if (m_TransferModule == null) |
95 | return; | ||
96 | |||
97 | IMessageTransferModule trans = m_SceneList[0].RequestModuleInterface<IMessageTransferModule>(); | ||
98 | if (trans == null) | ||
99 | { | 95 | { |
100 | enabled = false; | 96 | m_TransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); |
101 | 97 | if (m_TransferModule == null) | |
102 | lock (m_SceneList) | ||
103 | { | 98 | { |
104 | foreach (Scene s in m_SceneList) | 99 | scene.EventManager.OnNewClient -= OnNewClient; |
105 | s.EventManager.OnNewClient -= OnNewClient; | ||
106 | 100 | ||
101 | enabled = false; | ||
107 | m_SceneList.Clear(); | 102 | m_SceneList.Clear(); |
103 | |||
104 | m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages"); | ||
108 | } | 105 | } |
106 | m_TransferModule.OnUndeliveredMessage += UndeliveredMessage; | ||
107 | } | ||
108 | } | ||
109 | 109 | ||
110 | m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages"); | 110 | public void RemoveRegion(Scene scene) |
111 | { | ||
112 | if (!enabled) | ||
111 | return; | 113 | return; |
114 | |||
115 | lock (m_SceneList) | ||
116 | { | ||
117 | m_SceneList.Remove(scene); | ||
112 | } | 118 | } |
119 | } | ||
113 | 120 | ||
114 | trans.OnUndeliveredMessage += UndeliveredMessage; | 121 | public void PostInitialise() |
122 | { | ||
123 | if (!enabled) | ||
124 | return; | ||
115 | 125 | ||
116 | m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); | 126 | m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); |
117 | } | 127 | } |
@@ -121,9 +131,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
121 | get { return "OfflineMessageModule"; } | 131 | get { return "OfflineMessageModule"; } |
122 | } | 132 | } |
123 | 133 | ||
124 | public bool IsSharedModule | 134 | public Type ReplaceableInterface |
125 | { | 135 | { |
126 | get { return true; } | 136 | get { return null; } |
127 | } | 137 | } |
128 | 138 | ||
129 | public void Close() | 139 | public void Close() |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index f5ab454..267a90a 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs | |||
@@ -24,6 +24,7 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | ||
27 | using System.Collections; | 28 | using System.Collections; |
28 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
29 | using System.Net; | 30 | using System.Net; |
@@ -39,404 +40,54 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; | |||
39 | 40 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | 41 | namespace OpenSim.Region.CoreModules.Avatar.InstantMessage |
41 | { | 42 | { |
42 | public class PresenceModule : IRegionModule, IPresenceModule | 43 | public class PresenceModule : ISharedRegionModule, IPresenceModule |
43 | { | 44 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger( |
45 | 46 | MethodBase.GetCurrentMethod().DeclaringType); | |
46 | private bool m_Enabled = false; | ||
47 | private bool m_Gridmode = false; | ||
48 | |||
49 | // some default scene for doing things that aren't connected to a specific scene. Avoids locking. | ||
50 | private Scene m_initialScene; | ||
51 | |||
52 | private List<Scene> m_Scenes = new List<Scene>(); | ||
53 | |||
54 | // we currently are only interested in root-agents. If the root isn't here, we don't know the region the | ||
55 | // user is in, so we have to ask the messaging server anyway. | ||
56 | private Dictionary<UUID, Scene> m_RootAgents = | ||
57 | new Dictionary<UUID, Scene>(); | ||
58 | 47 | ||
59 | public event PresenceChange OnPresenceChange; | 48 | public event PresenceChange OnPresenceChange; |
60 | public event BulkPresenceData OnBulkPresenceData; | 49 | public event BulkPresenceData OnBulkPresenceData; |
61 | 50 | ||
62 | public void Initialise(Scene scene, IConfigSource config) | 51 | public void Initialise(IConfigSource config) |
63 | { | 52 | { |
64 | lock (m_Scenes) | ||
65 | { | ||
66 | // This is a shared module; Initialise will be called for every region on this server. | ||
67 | // Only check config once for the first region. | ||
68 | if (m_Scenes.Count == 0) | ||
69 | { | ||
70 | IConfig cnf = config.Configs["Messaging"]; | ||
71 | if (cnf != null && cnf.GetString( | ||
72 | "PresenceModule", "PresenceModule") != | ||
73 | "PresenceModule") | ||
74 | return; | ||
75 | |||
76 | cnf = config.Configs["Startup"]; | ||
77 | if (cnf != null) | ||
78 | m_Gridmode = cnf.GetBoolean("gridmode", false); | ||
79 | |||
80 | m_Enabled = true; | ||
81 | |||
82 | m_initialScene = scene; | ||
83 | } | ||
84 | |||
85 | if (m_Gridmode) | ||
86 | NotifyMessageServerOfStartup(scene); | ||
87 | |||
88 | m_Scenes.Add(scene); | ||
89 | } | ||
90 | |||
91 | scene.RegisterModuleInterface<IPresenceModule>(this); | ||
92 | |||
93 | scene.EventManager.OnNewClient += OnNewClient; | ||
94 | scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; | ||
95 | scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; | ||
96 | } | 53 | } |
97 | 54 | ||
98 | public void PostInitialise() | 55 | public void AddRegion(Scene scene) |
99 | { | 56 | { |
100 | } | 57 | } |
101 | 58 | ||
102 | public void Close() | 59 | public void RegionLoaded(Scene scene) |
103 | { | 60 | { |
104 | if (!m_Gridmode || !m_Enabled) | ||
105 | return; | ||
106 | |||
107 | if (OnPresenceChange != null) | ||
108 | { | ||
109 | lock (m_RootAgents) | ||
110 | { | ||
111 | // on shutdown, users are kicked, too | ||
112 | foreach (KeyValuePair<UUID, Scene> pair in m_RootAgents) | ||
113 | { | ||
114 | OnPresenceChange(new PresenceInfo(pair.Key, UUID.Zero)); | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | |||
119 | lock (m_Scenes) | ||
120 | { | ||
121 | foreach (Scene scene in m_Scenes) | ||
122 | NotifyMessageServerOfShutdown(scene); | ||
123 | } | ||
124 | } | 61 | } |
125 | 62 | ||
126 | public string Name | 63 | public void RemoveRegion(Scene scene) |
127 | { | 64 | { |
128 | get { return "PresenceModule"; } | ||
129 | } | ||
130 | |||
131 | public bool IsSharedModule | ||
132 | { | ||
133 | get { return true; } | ||
134 | } | ||
135 | |||
136 | public void RequestBulkPresenceData(UUID[] users) | ||
137 | { | ||
138 | if (OnBulkPresenceData != null) | ||
139 | { | ||
140 | PresenceInfo[] result = new PresenceInfo[users.Length]; | ||
141 | if (m_Gridmode) | ||
142 | { | ||
143 | // first check the local information | ||
144 | List<UUID> uuids = new List<UUID>(); // the uuids to check remotely | ||
145 | List<int> indices = new List<int>(); // just for performance. | ||
146 | lock (m_RootAgents) | ||
147 | { | ||
148 | for (int i = 0; i < uuids.Count; ++i) | ||
149 | { | ||
150 | Scene scene; | ||
151 | if (m_RootAgents.TryGetValue(users[i], out scene)) | ||
152 | { | ||
153 | result[i] = new PresenceInfo(users[i], scene.RegionInfo.RegionID); | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | uuids.Add(users[i]); | ||
158 | indices.Add(i); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | // now we have filtered out all the local root agents. The rest we have to request info about | ||
164 | Dictionary<UUID, FriendRegionInfo> infos = m_initialScene.GetFriendRegionInfos(uuids); | ||
165 | for (int i = 0; i < uuids.Count; ++i) | ||
166 | { | ||
167 | FriendRegionInfo info; | ||
168 | if (infos.TryGetValue(uuids[i], out info) && info.isOnline) | ||
169 | { | ||
170 | UUID regionID = info.regionID; | ||
171 | if (regionID == UUID.Zero) | ||
172 | { | ||
173 | // TODO this is the old messaging-server protocol; only the regionHandle is available. | ||
174 | // Fetch region-info to get the id | ||
175 | uint x = 0, y = 0; | ||
176 | Utils.LongToUInts(info.regionHandle, out x, out y); | ||
177 | GridRegion regionInfo = m_initialScene.GridService.GetRegionByPosition(m_initialScene.RegionInfo.ScopeID, | ||
178 | (int)x, (int)y); | ||
179 | regionID = regionInfo.RegionID; | ||
180 | } | ||
181 | result[indices[i]] = new PresenceInfo(uuids[i], regionID); | ||
182 | } | ||
183 | else result[indices[i]] = new PresenceInfo(uuids[i], UUID.Zero); | ||
184 | } | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | // in standalone mode, we have all the info locally available. | ||
189 | lock (m_RootAgents) | ||
190 | { | ||
191 | for (int i = 0; i < users.Length; ++i) | ||
192 | { | ||
193 | Scene scene; | ||
194 | if (m_RootAgents.TryGetValue(users[i], out scene)) | ||
195 | { | ||
196 | result[i] = new PresenceInfo(users[i], scene.RegionInfo.RegionID); | ||
197 | } | ||
198 | else | ||
199 | { | ||
200 | result[i] = new PresenceInfo(users[i], UUID.Zero); | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | // tell everyone | ||
207 | OnBulkPresenceData(result); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | // new client doesn't mean necessarily that user logged in, it just means it entered one of the | ||
212 | // the regions on this server | ||
213 | public void OnNewClient(IClientAPI client) | ||
214 | { | ||
215 | client.OnConnectionClosed += OnConnectionClosed; | ||
216 | client.OnLogout += OnLogout; | ||
217 | |||
218 | // KLUDGE: See handler for details. | ||
219 | client.OnEconomyDataRequest += OnEconomyDataRequest; | ||
220 | } | 65 | } |
221 | 66 | ||
222 | // connection closed just means *one* client connection has been closed. It doesn't mean that the | 67 | public void PostInitialise() |
223 | // user has logged off; it might have just TPed away. | ||
224 | public void OnConnectionClosed(IClientAPI client) | ||
225 | { | ||
226 | // TODO: Have to think what we have to do here... | ||
227 | // Should we just remove the root from the list (if scene matches)? | ||
228 | if (!(client.Scene is Scene)) | ||
229 | return; | ||
230 | Scene scene = (Scene)client.Scene; | ||
231 | |||
232 | lock (m_RootAgents) | ||
233 | { | ||
234 | Scene rootScene; | ||
235 | if (!(m_RootAgents.TryGetValue(client.AgentId, out rootScene)) || scene != rootScene) | ||
236 | return; | ||
237 | |||
238 | m_RootAgents.Remove(client.AgentId); | ||
239 | } | ||
240 | |||
241 | // Should it have logged off, we'll do the logout part in OnLogout, even if no root is stored | ||
242 | // anymore. It logged off, after all... | ||
243 | } | ||
244 | |||
245 | // Triggered when the user logs off. | ||
246 | public void OnLogout(IClientAPI client) | ||
247 | { | ||
248 | if (!(client.Scene is Scene)) | ||
249 | return; | ||
250 | Scene scene = (Scene)client.Scene; | ||
251 | |||
252 | // On logout, we really remove the client from rootAgents, even if the scene doesn't match | ||
253 | lock (m_RootAgents) | ||
254 | { | ||
255 | if (m_RootAgents.ContainsKey(client.AgentId)) m_RootAgents.Remove(client.AgentId); | ||
256 | } | ||
257 | |||
258 | // now inform the messaging server and anyone who is interested | ||
259 | NotifyMessageServerOfAgentLeaving(client.AgentId, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); | ||
260 | if (OnPresenceChange != null) OnPresenceChange(new PresenceInfo(client.AgentId, UUID.Zero)); | ||
261 | } | ||
262 | |||
263 | public void OnSetRootAgentScene(UUID agentID, Scene scene) | ||
264 | { | ||
265 | // OnSetRootAgentScene can be called from several threads at once (with different agentID). | ||
266 | // Concurrent access to m_RootAgents is prone to failure on multi-core/-processor systems without | ||
267 | // correct locking). | ||
268 | lock (m_RootAgents) | ||
269 | { | ||
270 | Scene rootScene; | ||
271 | if (m_RootAgents.TryGetValue(agentID, out rootScene) && scene == rootScene) | ||
272 | { | ||
273 | return; | ||
274 | } | ||
275 | m_RootAgents[agentID] = scene; | ||
276 | } | ||
277 | |||
278 | // inform messaging server that agent changed the region | ||
279 | Util.FireAndForget( | ||
280 | delegate(object o) | ||
281 | { | ||
282 | NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); | ||
283 | } | ||
284 | ); | ||
285 | } | ||
286 | |||
287 | private void OnEconomyDataRequest(UUID agentID) | ||
288 | { | 68 | { |
289 | // KLUDGE: This is the only way I found to get a message (only) after login was completed and the | ||
290 | // client is connected enough to receive UDP packets. | ||
291 | // This packet seems to be sent only once, just after connection was established to the first | ||
292 | // region after login. | ||
293 | // We use it here to trigger a presence update; the old update-on-login was never be heard by | ||
294 | // the freshly logged in viewer, as it wasn't connected to the region at that time. | ||
295 | // TODO: Feel free to replace this by a better solution if you find one. | ||
296 | |||
297 | // get the agent. This should work every time, as we just got a packet from it | ||
298 | ScenePresence agent = null; | ||
299 | lock (m_Scenes) | ||
300 | { | ||
301 | foreach (Scene scene in m_Scenes) | ||
302 | { | ||
303 | agent = scene.GetScenePresence(agentID); | ||
304 | if (agent != null) break; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | // just to be paranoid... | ||
309 | if (agent == null) | ||
310 | { | ||
311 | m_log.ErrorFormat("[PRESENCE]: Got a packet from agent {0} who can't be found anymore!?", agentID); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | // we are a bit premature here, but the next packet will switch this child agent to root. | ||
316 | if (OnPresenceChange != null) OnPresenceChange(new PresenceInfo(agentID, agent.Scene.RegionInfo.RegionID)); | ||
317 | } | 69 | } |
318 | 70 | ||
319 | public void OnMakeChildAgent(ScenePresence agent) | 71 | public void Close() |
320 | { | 72 | { |
321 | // OnMakeChildAgent can be called from several threads at once (with different agent). | ||
322 | // Concurrent access to m_RootAgents is prone to failure on multi-core/-processor systems without | ||
323 | // correct locking). | ||
324 | lock (m_RootAgents) | ||
325 | { | ||
326 | Scene rootScene; | ||
327 | if (m_RootAgents.TryGetValue(agent.UUID, out rootScene) && agent.Scene == rootScene) | ||
328 | { | ||
329 | m_RootAgents.Remove(agent.UUID); | ||
330 | } | ||
331 | } | ||
332 | // don't notify the messaging-server; either this agent just had been downgraded and another one will be upgraded | ||
333 | // to root momentarily (which will notify the messaging-server), or possibly it will be closed in a moment, | ||
334 | // which will update the messaging-server, too. | ||
335 | } | 73 | } |
336 | 74 | ||
337 | private void NotifyMessageServerOfStartup(Scene scene) | 75 | public string Name |
338 | { | 76 | { |
339 | Hashtable xmlrpcdata = new Hashtable(); | 77 | get { return "PresenceModule"; } |
340 | xmlrpcdata["RegionUUID"] = scene.RegionInfo.RegionID.ToString(); | ||
341 | ArrayList SendParams = new ArrayList(); | ||
342 | SendParams.Add(xmlrpcdata); | ||
343 | try | ||
344 | { | ||
345 | XmlRpcRequest UpRequest = new XmlRpcRequest("region_startup", SendParams); | ||
346 | XmlRpcResponse resp = UpRequest.Send(scene.CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
347 | |||
348 | Hashtable responseData = (Hashtable)resp.Value; | ||
349 | if (responseData == null || (!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
350 | { | ||
351 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region startup for region {0}", scene.RegionInfo.RegionName); | ||
352 | } | ||
353 | } | ||
354 | catch (WebException) | ||
355 | { | ||
356 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region startup for region {0}", scene.RegionInfo.RegionName); | ||
357 | } | ||
358 | } | 78 | } |
359 | 79 | ||
360 | private void NotifyMessageServerOfShutdown(Scene scene) | 80 | public Type ReplaceableInterface |
361 | { | 81 | { |
362 | if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) | 82 | get { return null; } |
363 | return; | ||
364 | |||
365 | Hashtable xmlrpcdata = new Hashtable(); | ||
366 | xmlrpcdata["RegionUUID"] = scene.RegionInfo.RegionID.ToString(); | ||
367 | ArrayList SendParams = new ArrayList(); | ||
368 | SendParams.Add(xmlrpcdata); | ||
369 | try | ||
370 | { | ||
371 | XmlRpcRequest DownRequest = new XmlRpcRequest("region_shutdown", SendParams); | ||
372 | XmlRpcResponse resp = DownRequest.Send(scene.CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
373 | |||
374 | Hashtable responseData = (Hashtable)resp.Value; | ||
375 | if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
376 | { | ||
377 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region shutdown for region {0}", scene.RegionInfo.RegionName); | ||
378 | } | ||
379 | } | ||
380 | catch (WebException) | ||
381 | { | ||
382 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of region shutdown for region {0}", scene.RegionInfo.RegionName); | ||
383 | } | ||
384 | } | 83 | } |
385 | 84 | ||
386 | private void NotifyMessageServerOfAgentLocation(UUID agentID, UUID region, ulong regionHandle) | 85 | public void RequestBulkPresenceData(UUID[] users) |
387 | { | 86 | { |
388 | if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) | ||
389 | return; | ||
390 | |||
391 | Hashtable xmlrpcdata = new Hashtable(); | ||
392 | xmlrpcdata["AgentID"] = agentID.ToString(); | ||
393 | xmlrpcdata["RegionUUID"] = region.ToString(); | ||
394 | xmlrpcdata["RegionHandle"] = regionHandle.ToString(); | ||
395 | ArrayList SendParams = new ArrayList(); | ||
396 | SendParams.Add(xmlrpcdata); | ||
397 | try | ||
398 | { | ||
399 | XmlRpcRequest LocationRequest = new XmlRpcRequest("agent_location", SendParams); | ||
400 | XmlRpcResponse resp = LocationRequest.Send(m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
401 | |||
402 | Hashtable responseData = (Hashtable)resp.Value; | ||
403 | if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
404 | { | ||
405 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent location for {0}", agentID.ToString()); | ||
406 | } | ||
407 | } | ||
408 | catch (WebException) | ||
409 | { | ||
410 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent location for {0}", agentID.ToString()); | ||
411 | } | ||
412 | } | 87 | } |
413 | 88 | ||
414 | private void NotifyMessageServerOfAgentLeaving(UUID agentID, UUID region, ulong regionHandle) | 89 | public void OnNewClient(IClientAPI client) |
415 | { | 90 | { |
416 | if (m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL == string.Empty) | ||
417 | return; | ||
418 | |||
419 | Hashtable xmlrpcdata = new Hashtable(); | ||
420 | xmlrpcdata["AgentID"] = agentID.ToString(); | ||
421 | xmlrpcdata["RegionUUID"] = region.ToString(); | ||
422 | xmlrpcdata["RegionHandle"] = regionHandle.ToString(); | ||
423 | ArrayList SendParams = new ArrayList(); | ||
424 | SendParams.Add(xmlrpcdata); | ||
425 | try | ||
426 | { | ||
427 | XmlRpcRequest LeavingRequest = new XmlRpcRequest("agent_leaving", SendParams); | ||
428 | XmlRpcResponse resp = LeavingRequest.Send(m_Scenes[0].CommsManager.NetworkServersInfo.MessagingURL, 5000); | ||
429 | |||
430 | Hashtable responseData = (Hashtable)resp.Value; | ||
431 | if ((!responseData.ContainsKey("success")) || (string)responseData["success"] != "TRUE") | ||
432 | { | ||
433 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent leaving for {0}", agentID.ToString()); | ||
434 | } | ||
435 | } | ||
436 | catch (WebException) | ||
437 | { | ||
438 | m_log.ErrorFormat("[PRESENCE]: Failed to notify message server of agent leaving for {0}", agentID.ToString()); | ||
439 | } | ||
440 | } | 91 | } |
441 | } | 92 | } |
442 | } | 93 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index d9a021f..55d4f14 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -39,7 +39,7 @@ using OpenSim.Services.Interfaces; | |||
39 | 39 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | 40 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer |
41 | { | 41 | { |
42 | public class InventoryTransferModule : IInventoryTransferModule, IRegionModule | 42 | public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule |
43 | { | 43 | { |
44 | private static readonly ILog m_log | 44 | private static readonly ILog m_log |
45 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -50,10 +50,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
50 | new Dictionary<UUID, Scene>(); | 50 | new Dictionary<UUID, Scene>(); |
51 | 51 | ||
52 | private IMessageTransferModule m_TransferModule = null; | 52 | private IMessageTransferModule m_TransferModule = null; |
53 | private bool m_Enabled = true; | ||
53 | 54 | ||
54 | #region IRegionModule Members | 55 | #region IRegionModule Members |
55 | 56 | ||
56 | public void Initialise(Scene scene, IConfigSource config) | 57 | public void Initialise(IConfigSource config) |
57 | { | 58 | { |
58 | if (config.Configs["Messaging"] != null) | 59 | if (config.Configs["Messaging"] != null) |
59 | { | 60 | { |
@@ -62,29 +63,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
62 | if (config.Configs["Messaging"].GetString( | 63 | if (config.Configs["Messaging"].GetString( |
63 | "InventoryTransferModule", "InventoryTransferModule") != | 64 | "InventoryTransferModule", "InventoryTransferModule") != |
64 | "InventoryTransferModule") | 65 | "InventoryTransferModule") |
66 | { | ||
67 | m_Enabled = false; | ||
65 | return; | 68 | return; |
69 | } | ||
66 | } | 70 | } |
71 | } | ||
67 | 72 | ||
68 | if (!m_Scenelist.Contains(scene)) | 73 | public void AddRegion(Scene scene) |
69 | { | 74 | { |
70 | m_Scenelist.Add(scene); | 75 | if (!m_Enabled) |
76 | return; | ||
71 | 77 | ||
72 | scene.RegisterModuleInterface<IInventoryTransferModule>(this); | 78 | m_Scenelist.Add(scene); |
73 | 79 | ||
74 | scene.EventManager.OnNewClient += OnNewClient; | 80 | scene.RegisterModuleInterface<IInventoryTransferModule>(this); |
75 | scene.EventManager.OnClientClosed += ClientLoggedOut; | 81 | |
76 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | 82 | scene.EventManager.OnNewClient += OnNewClient; |
77 | } | 83 | scene.EventManager.OnClientClosed += ClientLoggedOut; |
84 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | ||
78 | } | 85 | } |
79 | 86 | ||
80 | public void PostInitialise() | 87 | public void RegionLoaded(Scene scene) |
81 | { | 88 | { |
82 | if (m_Scenelist.Count > 0) | 89 | if (m_TransferModule == null) |
83 | { | 90 | { |
84 | m_TransferModule = m_Scenelist[0].RequestModuleInterface<IMessageTransferModule>(); | 91 | m_TransferModule = m_Scenelist[0].RequestModuleInterface<IMessageTransferModule>(); |
85 | if (m_TransferModule == null) | 92 | if (m_TransferModule == null) |
93 | { | ||
86 | m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); | 94 | m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); |
95 | m_Enabled = false; | ||
96 | |||
97 | m_Scenelist.Clear(); | ||
98 | scene.EventManager.OnNewClient -= OnNewClient; | ||
99 | scene.EventManager.OnClientClosed -= ClientLoggedOut; | ||
100 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | ||
101 | } | ||
87 | } | 102 | } |
103 | |||
104 | } | ||
105 | |||
106 | public void RemoveRegion(Scene scene) | ||
107 | { | ||
108 | scene.EventManager.OnNewClient -= OnNewClient; | ||
109 | scene.EventManager.OnClientClosed -= ClientLoggedOut; | ||
110 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | ||
111 | m_Scenelist.Remove(scene); | ||
112 | } | ||
113 | |||
114 | public void PostInitialise() | ||
115 | { | ||
88 | } | 116 | } |
89 | 117 | ||
90 | public void Close() | 118 | public void Close() |
@@ -96,9 +124,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
96 | get { return "InventoryModule"; } | 124 | get { return "InventoryModule"; } |
97 | } | 125 | } |
98 | 126 | ||
99 | public bool IsSharedModule | 127 | public Type ReplaceableInterface |
100 | { | 128 | { |
101 | get { return true; } | 129 | get { return null; } |
102 | } | 130 | } |
103 | 131 | ||
104 | #endregion | 132 | #endregion |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index 261bd6c..d1d7df2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -37,34 +37,72 @@ using OpenSim.Region.Framework.Scenes; | |||
37 | 37 | ||
38 | namespace OpenSim.Region.CoreModules.Avatar.Lure | 38 | namespace OpenSim.Region.CoreModules.Avatar.Lure |
39 | { | 39 | { |
40 | public class LureModule : IRegionModule | 40 | public class LureModule : ISharedRegionModule |
41 | { | 41 | { |
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | private static readonly ILog m_log = LogManager.GetLogger( |
43 | MethodBase.GetCurrentMethod().DeclaringType); | ||
43 | 44 | ||
44 | private readonly List<Scene> m_scenes = new List<Scene>(); | 45 | private readonly List<Scene> m_scenes = new List<Scene>(); |
45 | 46 | ||
46 | private IMessageTransferModule m_TransferModule = null; | 47 | private IMessageTransferModule m_TransferModule = null; |
48 | private bool m_Enabled = true; | ||
47 | 49 | ||
48 | public void Initialise(Scene scene, IConfigSource config) | 50 | public void Initialise(IConfigSource config) |
49 | { | 51 | { |
50 | if (config.Configs["Messaging"] != null) | 52 | if (config.Configs["Messaging"] != null) |
51 | { | 53 | { |
52 | if (config.Configs["Messaging"].GetString( | 54 | if (config.Configs["Messaging"].GetString( |
53 | "LureModule", "LureModule") != | 55 | "LureModule", "LureModule") != |
54 | "LureModule") | 56 | "LureModule") |
55 | return; | 57 | m_Enabled = false; |
56 | } | 58 | } |
59 | } | ||
60 | |||
61 | public void AddRegion(Scene scene) | ||
62 | { | ||
63 | if (!m_Enabled) | ||
64 | return; | ||
57 | 65 | ||
58 | lock (m_scenes) | 66 | lock (m_scenes) |
59 | { | 67 | { |
60 | if (!m_scenes.Contains(scene)) | 68 | m_scenes.Add(scene); |
69 | scene.EventManager.OnNewClient += OnNewClient; | ||
70 | scene.EventManager.OnIncomingInstantMessage += | ||
71 | OnGridInstantMessage; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public void RegionLoaded(Scene scene) | ||
76 | { | ||
77 | if (m_TransferModule == null) | ||
78 | { | ||
79 | m_TransferModule = | ||
80 | scene.RequestModuleInterface<IMessageTransferModule>(); | ||
81 | |||
82 | if (m_TransferModule == null) | ||
61 | { | 83 | { |
62 | m_scenes.Add(scene); | 84 | m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ |
63 | scene.EventManager.OnNewClient += OnNewClient; | 85 | "lures will not work!"); |
64 | scene.EventManager.OnIncomingInstantMessage += | 86 | |
87 | m_Enabled = false; | ||
88 | m_scenes.Clear(); | ||
89 | scene.EventManager.OnNewClient -= OnNewClient; | ||
90 | scene.EventManager.OnIncomingInstantMessage -= | ||
65 | OnGridInstantMessage; | 91 | OnGridInstantMessage; |
66 | } | 92 | } |
67 | } | 93 | } |
94 | |||
95 | } | ||
96 | |||
97 | public void RemoveRegion(Scene scene) | ||
98 | { | ||
99 | lock (m_scenes) | ||
100 | { | ||
101 | m_scenes.Remove(scene); | ||
102 | scene.EventManager.OnNewClient -= OnNewClient; | ||
103 | scene.EventManager.OnIncomingInstantMessage -= | ||
104 | OnGridInstantMessage; | ||
105 | } | ||
68 | } | 106 | } |
69 | 107 | ||
70 | void OnNewClient(IClientAPI client) | 108 | void OnNewClient(IClientAPI client) |
@@ -76,12 +114,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
76 | 114 | ||
77 | public void PostInitialise() | 115 | public void PostInitialise() |
78 | { | 116 | { |
79 | m_TransferModule = | ||
80 | m_scenes[0].RequestModuleInterface<IMessageTransferModule>(); | ||
81 | |||
82 | if (m_TransferModule == null) | ||
83 | m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ | ||
84 | "lures will not work!"); | ||
85 | } | 117 | } |
86 | 118 | ||
87 | public void Close() | 119 | public void Close() |
@@ -93,9 +125,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
93 | get { return "LureModule"; } | 125 | get { return "LureModule"; } |
94 | } | 126 | } |
95 | 127 | ||
96 | public bool IsSharedModule | 128 | public Type ReplaceableInterface |
97 | { | 129 | { |
98 | get { return true; } | 130 | get { return null; } |
99 | } | 131 | } |
100 | 132 | ||
101 | public void OnInstantMessage(IClientAPI client, GridInstantMessage im) | 133 | public void OnInstantMessage(IClientAPI client, GridInstantMessage im) |
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index beb2307..e4b0fd5 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | |||
@@ -17,13 +17,19 @@ | |||
17 | <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" /> | 17 | <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" /> |
18 | <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> | 18 | <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> |
19 | <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" /> | 19 | <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" /> |
20 | <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" /> | ||
21 | <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" /> | ||
22 | <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" /> | ||
23 | <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" /> | ||
24 | <RegionModule id="InstantMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.InstantMessageModule" /> | ||
25 | <RegionModule id="MessageTransferModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MessageTransferModule" /> | ||
26 | <RegionModule id="LureModule" type="OpenSim.Region.CoreModules.Avatar.Lure.LureModule" /> | ||
27 | <RegionModule id="InventoryTransferModule" type="OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.InventoryTransferModule" /> | ||
20 | <RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" /> | 28 | <RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" /> |
21 | <RegionModule id="GlynnTuckerAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" /> | 29 | <RegionModule id="GlynnTuckerAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" /> |
22 | <RegionModule id="CenomeMemoryAssetCache" type="OpenSim.Region.CoreModules.Asset.CenomeMemoryAssetCache"/> | 30 | <RegionModule id="CenomeMemoryAssetCache" type="OpenSim.Region.CoreModules.Asset.CenomeMemoryAssetCache"/> |
23 | <RegionModule id="LibraryModule" type="OpenSim.Region.CoreModules.Framework.Library.LibraryModule"/> | 31 | <RegionModule id="LibraryModule" type="OpenSim.Region.CoreModules.Framework.Library.LibraryModule"/> |
24 | <!-- Service connectors OUT modules --> | 32 | <!-- Service connectors OUT modules --> |
25 | <RegionModule id="LocalUserServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.User.LocalUserServicesConnector" /> | ||
26 | <RegionModule id="RemoteUserServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.User.RemoteUserServicesConnector" /> | ||
27 | <RegionModule id="LocalAssetServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.LocalAssetServicesConnector" /> | 33 | <RegionModule id="LocalAssetServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.LocalAssetServicesConnector" /> |
28 | <RegionModule id="RemoteAssetServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.RemoteAssetServicesConnector" /> | 34 | <RegionModule id="RemoteAssetServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.RemoteAssetServicesConnector" /> |
29 | <RegionModule id="LocalAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.LocalAuthorizationServicesConnector" /> | 35 | <RegionModule id="LocalAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.LocalAuthorizationServicesConnector" /> |
@@ -41,6 +47,10 @@ | |||
41 | <RegionModule id="LocalGridServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.LocalGridServicesConnector" /> | 47 | <RegionModule id="LocalGridServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.LocalGridServicesConnector" /> |
42 | <RegionModule id="RemoteGridServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.RemoteGridServicesConnector" /> | 48 | <RegionModule id="RemoteGridServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.RemoteGridServicesConnector" /> |
43 | <RegionModule id="HGGridConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.HGGridConnector" /> | 49 | <RegionModule id="HGGridConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.HGGridConnector" /> |
50 | <RegionModule id="LocalPresenceServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.LocalPresenceServicesConnector" /> | ||
51 | <RegionModule id="RemotePresenceServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.RemotePresenceServicesConnector" /> | ||
52 | <RegionModule id="LocalUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.LocalUserAccountServicesConnector" /> | ||
53 | <RegionModule id="RemoteUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.RemoteUserAccountServicesConnector" /> | ||
44 | <!-- Service connectors IN modules --> | 54 | <!-- Service connectors IN modules --> |
45 | <RegionModule id="AssetServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset.AssetServiceInConnectorModule" /> | 55 | <RegionModule id="AssetServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset.AssetServiceInConnectorModule" /> |
46 | <RegionModule id="InventoryServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory.InventoryServiceInConnectorModule" /> | 56 | <RegionModule id="InventoryServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory.InventoryServiceInConnectorModule" /> |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs new file mode 100644 index 0000000..2cb18c7 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs | |||
@@ -0,0 +1,200 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Reflection; | ||
30 | |||
31 | using OpenSim.Region.Framework.Interfaces; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenSim.Server.Base; | ||
34 | using OpenSim.Services.Interfaces; | ||
35 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | ||
36 | |||
37 | using OpenMetaverse; | ||
38 | using log4net; | ||
39 | using Nini.Config; | ||
40 | |||
41 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | ||
42 | { | ||
43 | public class LocalPresenceServicesConnector : ISharedRegionModule, IPresenceService | ||
44 | { | ||
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
47 | private bool m_Enabled = false; | ||
48 | |||
49 | private PresenceDetector m_PresenceDetector; | ||
50 | private IPresenceService m_PresenceService; | ||
51 | |||
52 | public LocalPresenceServicesConnector() | ||
53 | { | ||
54 | } | ||
55 | |||
56 | public LocalPresenceServicesConnector(IConfigSource source) | ||
57 | { | ||
58 | Initialise(source); | ||
59 | } | ||
60 | |||
61 | #region ISharedRegionModule | ||
62 | |||
63 | public Type ReplaceableInterface | ||
64 | { | ||
65 | get { return null; } | ||
66 | } | ||
67 | |||
68 | public string Name | ||
69 | { | ||
70 | get { return "LocalPresenceServicesConnector"; } | ||
71 | } | ||
72 | |||
73 | public void Initialise(IConfigSource source) | ||
74 | { | ||
75 | IConfig moduleConfig = source.Configs["Modules"]; | ||
76 | if (moduleConfig != null) | ||
77 | { | ||
78 | string name = moduleConfig.GetString("PresenceServices", ""); | ||
79 | if (name == Name) | ||
80 | { | ||
81 | IConfig inventoryConfig = source.Configs["PresenceService"]; | ||
82 | if (inventoryConfig == null) | ||
83 | { | ||
84 | m_log.Error("[LOCAL PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | string serviceDll = inventoryConfig.GetString("LocalServiceModule", String.Empty); | ||
89 | |||
90 | if (serviceDll == String.Empty) | ||
91 | { | ||
92 | m_log.Error("[LOCAL PRESENCE CONNECTOR]: No LocalServiceModule named in section PresenceService"); | ||
93 | return; | ||
94 | } | ||
95 | |||
96 | Object[] args = new Object[] { source }; | ||
97 | m_log.DebugFormat("[LOCAL PRESENCE CONNECTOR]: Service dll = {0}", serviceDll); | ||
98 | |||
99 | m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(serviceDll, args); | ||
100 | |||
101 | if (m_PresenceService == null) | ||
102 | { | ||
103 | m_log.Error("[LOCAL PRESENCE CONNECTOR]: Can't load presence service"); | ||
104 | //return; | ||
105 | throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's"); | ||
106 | } | ||
107 | |||
108 | //Init(source); | ||
109 | |||
110 | m_PresenceDetector = new PresenceDetector(this); | ||
111 | |||
112 | m_Enabled = true; | ||
113 | m_log.Info("[LOCAL PRESENCE CONNECTOR]: Local presence connector enabled"); | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | public void PostInitialise() | ||
119 | { | ||
120 | } | ||
121 | |||
122 | public void Close() | ||
123 | { | ||
124 | } | ||
125 | |||
126 | public void AddRegion(Scene scene) | ||
127 | { | ||
128 | if (!m_Enabled) | ||
129 | return; | ||
130 | |||
131 | // m_log.DebugFormat( | ||
132 | // "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName); | ||
133 | |||
134 | scene.RegisterModuleInterface<IPresenceService>(this); | ||
135 | m_PresenceDetector.AddRegion(scene); | ||
136 | |||
137 | m_log.InfoFormat("[LOCAL PRESENCE CONNECTOR]: Enabled local presence for region {0}", scene.RegionInfo.RegionName); | ||
138 | |||
139 | } | ||
140 | |||
141 | public void RemoveRegion(Scene scene) | ||
142 | { | ||
143 | if (!m_Enabled) | ||
144 | return; | ||
145 | |||
146 | m_PresenceDetector.RemoveRegion(scene); | ||
147 | } | ||
148 | |||
149 | public void RegionLoaded(Scene scene) | ||
150 | { | ||
151 | if (!m_Enabled) | ||
152 | return; | ||
153 | |||
154 | } | ||
155 | |||
156 | #endregion | ||
157 | |||
158 | #region IPresenceService | ||
159 | |||
160 | public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) | ||
161 | { | ||
162 | m_log.Warn("[LOCAL PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators"); | ||
163 | return false; | ||
164 | } | ||
165 | |||
166 | public bool LogoutAgent(UUID sessionID) | ||
167 | { | ||
168 | return m_PresenceService.LogoutAgent(sessionID); | ||
169 | } | ||
170 | |||
171 | |||
172 | public bool LogoutRegionAgents(UUID regionID) | ||
173 | { | ||
174 | return m_PresenceService.LogoutRegionAgents(regionID); | ||
175 | } | ||
176 | |||
177 | public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
178 | { | ||
179 | return m_PresenceService.ReportAgent(sessionID, regionID, position, lookAt); | ||
180 | } | ||
181 | |||
182 | public PresenceInfo GetAgent(UUID sessionID) | ||
183 | { | ||
184 | return m_PresenceService.GetAgent(sessionID); | ||
185 | } | ||
186 | |||
187 | public PresenceInfo[] GetAgents(string[] userIDs) | ||
188 | { | ||
189 | return m_PresenceService.GetAgents(userIDs); | ||
190 | } | ||
191 | |||
192 | public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
193 | { | ||
194 | return m_PresenceService.SetHomeLocation(userID, regionID, position, lookAt); | ||
195 | } | ||
196 | |||
197 | #endregion | ||
198 | |||
199 | } | ||
200 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs new file mode 100644 index 0000000..3ca5560 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Reflection; | ||
30 | |||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenSim.Services.Interfaces; | ||
34 | |||
35 | using OpenMetaverse; | ||
36 | using log4net; | ||
37 | |||
38 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | ||
39 | { | ||
40 | public class PresenceDetector | ||
41 | { | ||
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
43 | |||
44 | private IPresenceService m_PresenceService; | ||
45 | |||
46 | public PresenceDetector(IPresenceService presenceservice) | ||
47 | { | ||
48 | m_PresenceService = presenceservice; | ||
49 | } | ||
50 | |||
51 | public void AddRegion(Scene scene) | ||
52 | { | ||
53 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; | ||
54 | scene.EventManager.OnNewClient += OnNewClient; | ||
55 | |||
56 | m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID); | ||
57 | } | ||
58 | |||
59 | public void RemoveRegion(Scene scene) | ||
60 | { | ||
61 | scene.EventManager.OnMakeRootAgent -= OnMakeRootAgent; | ||
62 | scene.EventManager.OnNewClient -= OnNewClient; | ||
63 | |||
64 | m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID); | ||
65 | } | ||
66 | |||
67 | public void OnMakeRootAgent(ScenePresence sp) | ||
68 | { | ||
69 | m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); | ||
70 | m_PresenceService.ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); | ||
71 | } | ||
72 | |||
73 | public void OnNewClient(IClientAPI client) | ||
74 | { | ||
75 | client.OnLogout += OnLogout; | ||
76 | } | ||
77 | |||
78 | public void OnLogout(IClientAPI client) | ||
79 | { | ||
80 | client.OnLogout -= OnLogout; | ||
81 | m_PresenceService.LogoutAgent(client.SessionId); | ||
82 | } | ||
83 | } | ||
84 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs new file mode 100644 index 0000000..e8e140a --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Reflection; | ||
30 | |||
31 | using OpenSim.Region.Framework.Interfaces; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenSim.Server.Base; | ||
34 | using OpenSim.Services.Interfaces; | ||
35 | using OpenSim.Services.Connectors; | ||
36 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | ||
37 | |||
38 | using OpenMetaverse; | ||
39 | using log4net; | ||
40 | using Nini.Config; | ||
41 | |||
42 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | ||
43 | { | ||
44 | public class RemotePresenceServicesConnector : ISharedRegionModule, IPresenceService | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | #region ISharedRegionModule | ||
49 | |||
50 | private bool m_Enabled = false; | ||
51 | |||
52 | private PresenceDetector m_PresenceDetector; | ||
53 | private IPresenceService m_RemoteConnector; | ||
54 | |||
55 | public Type ReplaceableInterface | ||
56 | { | ||
57 | get { return null; } | ||
58 | } | ||
59 | |||
60 | public string Name | ||
61 | { | ||
62 | get { return "RemotePresenceServiceConnector"; } | ||
63 | } | ||
64 | |||
65 | public void Initialise(IConfigSource source) | ||
66 | { | ||
67 | IConfig moduleConfig = source.Configs["Modules"]; | ||
68 | if (moduleConfig != null) | ||
69 | { | ||
70 | string name = moduleConfig.GetString("PresenceServices", ""); | ||
71 | if (name == Name) | ||
72 | { | ||
73 | m_RemoteConnector = new PresenceServicesConnector(source); | ||
74 | |||
75 | m_Enabled = true; | ||
76 | |||
77 | m_PresenceDetector = new PresenceDetector(this); | ||
78 | |||
79 | m_log.Info("[INVENTORY CONNECTOR]: Remote presence enabled"); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | } | ||
84 | |||
85 | public void PostInitialise() | ||
86 | { | ||
87 | } | ||
88 | |||
89 | public void Close() | ||
90 | { | ||
91 | } | ||
92 | |||
93 | public void AddRegion(Scene scene) | ||
94 | { | ||
95 | if (!m_Enabled) | ||
96 | return; | ||
97 | |||
98 | scene.RegisterModuleInterface<IPresenceService>(this); | ||
99 | m_PresenceDetector.AddRegion(scene); | ||
100 | |||
101 | m_log.InfoFormat("[REMOTE PRESENCE CONNECTOR]: Enabled remote presence for region {0}", scene.RegionInfo.RegionName); | ||
102 | |||
103 | } | ||
104 | |||
105 | public void RemoveRegion(Scene scene) | ||
106 | { | ||
107 | if (!m_Enabled) | ||
108 | return; | ||
109 | |||
110 | m_PresenceDetector.RemoveRegion(scene); | ||
111 | } | ||
112 | |||
113 | public void RegionLoaded(Scene scene) | ||
114 | { | ||
115 | if (!m_Enabled) | ||
116 | return; | ||
117 | |||
118 | } | ||
119 | |||
120 | #endregion | ||
121 | |||
122 | #region IPresenceService | ||
123 | |||
124 | public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) | ||
125 | { | ||
126 | m_log.Warn("[REMOTE PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators"); | ||
127 | return false; | ||
128 | } | ||
129 | |||
130 | public bool LogoutAgent(UUID sessionID) | ||
131 | { | ||
132 | return m_RemoteConnector.LogoutAgent(sessionID); | ||
133 | } | ||
134 | |||
135 | |||
136 | public bool LogoutRegionAgents(UUID regionID) | ||
137 | { | ||
138 | return m_RemoteConnector.LogoutRegionAgents(regionID); | ||
139 | } | ||
140 | |||
141 | public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
142 | { | ||
143 | return m_RemoteConnector.ReportAgent(sessionID, regionID, position, lookAt); | ||
144 | } | ||
145 | |||
146 | public PresenceInfo GetAgent(UUID sessionID) | ||
147 | { | ||
148 | return m_RemoteConnector.GetAgent(sessionID); | ||
149 | } | ||
150 | |||
151 | public PresenceInfo[] GetAgents(string[] userIDs) | ||
152 | { | ||
153 | return m_RemoteConnector.GetAgents(userIDs); | ||
154 | } | ||
155 | |||
156 | public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
157 | { | ||
158 | return m_RemoteConnector.SetHomeLocation(userID, regionID, position, lookAt); | ||
159 | } | ||
160 | |||
161 | #endregion | ||
162 | |||
163 | } | ||
164 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs new file mode 100644 index 0000000..ebb2c3e --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net.Config; | ||
34 | using NUnit.Framework; | ||
35 | using NUnit.Framework.SyntaxHelpers; | ||
36 | using OpenMetaverse; | ||
37 | using OpenSim.Framework; | ||
38 | using Nini.Config; | ||
39 | |||
40 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | ||
43 | using OpenSim.Tests.Common; | ||
44 | using OpenSim.Tests.Common.Setup; | ||
45 | |||
46 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests | ||
47 | { | ||
48 | [TestFixture] | ||
49 | public class PresenceConnectorsTests | ||
50 | { | ||
51 | LocalPresenceServicesConnector m_LocalConnector; | ||
52 | private void SetUp() | ||
53 | { | ||
54 | IConfigSource config = new IniConfigSource(); | ||
55 | config.AddConfig("Modules"); | ||
56 | config.AddConfig("PresenceService"); | ||
57 | config.Configs["Modules"].Set("PresenceServices", "LocalPresenceServicesConnector"); | ||
58 | config.Configs["PresenceService"].Set("LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService"); | ||
59 | config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll:NullPresenceData"); | ||
60 | |||
61 | m_LocalConnector = new LocalPresenceServicesConnector(config); | ||
62 | } | ||
63 | |||
64 | /// <summary> | ||
65 | /// Test OpenSim Presence. | ||
66 | /// </summary> | ||
67 | [Test] | ||
68 | public void TestPresenceV0_1() | ||
69 | { | ||
70 | SetUp(); | ||
71 | |||
72 | string user1 = UUID.Zero.ToString(); | ||
73 | UUID session1 = UUID.Zero; | ||
74 | |||
75 | // this is not implemented by this connector | ||
76 | //m_LocalConnector.LoginAgent(user1, session1, UUID.Zero); | ||
77 | PresenceInfo result = m_LocalConnector.GetAgent(session1); | ||
78 | Assert.IsNotNull(result, "Retrieved GetAgent is null"); | ||
79 | Assert.That(result.UserID, Is.EqualTo(user1), "Retrieved userID does not match"); | ||
80 | Assert.IsTrue(result.Online, "Agent just logged in but is offline"); | ||
81 | |||
82 | UUID region1 = UUID.Random(); | ||
83 | bool r = m_LocalConnector.ReportAgent(session1, region1, Vector3.Zero, Vector3.Zero); | ||
84 | Assert.IsTrue(r, "First ReportAgent returned false"); | ||
85 | result = m_LocalConnector.GetAgent(session1); | ||
86 | Assert.That(result.RegionID, Is.EqualTo(region1), "Agent is not in the right region (region1)"); | ||
87 | |||
88 | UUID region2 = UUID.Random(); | ||
89 | r = m_LocalConnector.ReportAgent(session1, region2, Vector3.Zero, Vector3.Zero); | ||
90 | Assert.IsTrue(r, "Second ReportAgent returned false"); | ||
91 | result = m_LocalConnector.GetAgent(session1); | ||
92 | Assert.That(result.RegionID, Is.EqualTo(region2), "Agent is not in the right region (region2)"); | ||
93 | |||
94 | r = m_LocalConnector.LogoutAgent(session1); | ||
95 | Assert.IsTrue(r, "LogoutAgent returned false"); | ||
96 | result = m_LocalConnector.GetAgent(session1); | ||
97 | Assert.IsNotNull(result, "Agent session disappeared from storage after logout"); | ||
98 | Assert.IsFalse(result.Online, "Agent is reported to be Online after logout"); | ||
99 | |||
100 | r = m_LocalConnector.ReportAgent(session1, region1, Vector3.Zero, Vector3.Zero); | ||
101 | Assert.IsFalse(r, "ReportAgent of non-logged in user returned true"); | ||
102 | } | ||
103 | } | ||
104 | } | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/User/LocalUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs index cca5bb4..ce8c3a5 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/User/LocalUserServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using log4net; | 31 | using log4net; |
31 | using Nini.Config; | 32 | using Nini.Config; |
@@ -34,9 +35,11 @@ using OpenSim.Region.Framework.Scenes; | |||
34 | using OpenSim.Server.Base; | 35 | using OpenSim.Server.Base; |
35 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | 38 | using OpenMetaverse; |
39 | |||
40 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts | ||
38 | { | 41 | { |
39 | public class LocalUserServicesConnector : ISharedRegionModule | 42 | public class LocalUserAccountServicesConnector : ISharedRegionModule, IUserAccountService |
40 | { | 43 | { |
41 | private static readonly ILog m_log = | 44 | private static readonly ILog m_log = |
42 | LogManager.GetLogger( | 45 | LogManager.GetLogger( |
@@ -46,6 +49,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | |||
46 | 49 | ||
47 | private bool m_Enabled = false; | 50 | private bool m_Enabled = false; |
48 | 51 | ||
52 | #region ISharedRegionModule | ||
53 | |||
49 | public Type ReplaceableInterface | 54 | public Type ReplaceableInterface |
50 | { | 55 | { |
51 | get { return null; } | 56 | get { return null; } |
@@ -53,7 +58,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | |||
53 | 58 | ||
54 | public string Name | 59 | public string Name |
55 | { | 60 | { |
56 | get { return "LocalUserServicesConnector"; } | 61 | get { return "LocalUserAccountServicesConnector"; } |
57 | } | 62 | } |
58 | 63 | ||
59 | public void Initialise(IConfigSource source) | 64 | public void Initialise(IConfigSource source) |
@@ -61,13 +66,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | |||
61 | IConfig moduleConfig = source.Configs["Modules"]; | 66 | IConfig moduleConfig = source.Configs["Modules"]; |
62 | if (moduleConfig != null) | 67 | if (moduleConfig != null) |
63 | { | 68 | { |
64 | string name = moduleConfig.GetString("UserServices", ""); | 69 | string name = moduleConfig.GetString("UserAccountServices", ""); |
65 | if (name == Name) | 70 | if (name == Name) |
66 | { | 71 | { |
67 | IConfig userConfig = source.Configs["UserService"]; | 72 | IConfig userConfig = source.Configs["UserAccountService"]; |
68 | if (userConfig == null) | 73 | if (userConfig == null) |
69 | { | 74 | { |
70 | m_log.Error("[USER CONNECTOR]: UserService missing from OpenSim.ini"); | 75 | m_log.Error("[USER CONNECTOR]: UserAccountService missing from OpenSim.ini"); |
71 | return; | 76 | return; |
72 | } | 77 | } |
73 | 78 | ||
@@ -87,7 +92,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | |||
87 | 92 | ||
88 | if (m_UserService == null) | 93 | if (m_UserService == null) |
89 | { | 94 | { |
90 | m_log.Error("[USER CONNECTOR]: Can't load user service"); | 95 | m_log.Error("[USER CONNECTOR]: Can't load user account service"); |
91 | return; | 96 | return; |
92 | } | 97 | } |
93 | m_Enabled = true; | 98 | m_Enabled = true; |
@@ -127,5 +132,45 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | |||
127 | if (!m_Enabled) | 132 | if (!m_Enabled) |
128 | return; | 133 | return; |
129 | } | 134 | } |
135 | |||
136 | #endregion | ||
137 | |||
138 | #region IUserAccountService | ||
139 | |||
140 | public UserAccount GetUserAccount(UUID scopeID, UUID userID) | ||
141 | { | ||
142 | return m_UserService.GetUserAccount(scopeID, userID); | ||
143 | } | ||
144 | |||
145 | public UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName) | ||
146 | { | ||
147 | return m_UserService.GetUserAccount(scopeID, FirstName, LastName); | ||
148 | } | ||
149 | |||
150 | public UserAccount GetUserAccount(UUID scopeID, string Email) | ||
151 | { | ||
152 | return m_UserService.GetUserAccount(scopeID, Email); | ||
153 | } | ||
154 | |||
155 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) | ||
156 | { | ||
157 | return m_UserService.GetUserAccounts(scopeID, query); | ||
158 | } | ||
159 | |||
160 | // Update all updatable fields | ||
161 | // | ||
162 | public bool SetUserAccount(UserAccount data) | ||
163 | { | ||
164 | return m_UserService.SetUserAccount(data); | ||
165 | } | ||
166 | |||
167 | // Creates a user data record | ||
168 | public bool CreateUserAccount(UserAccount data) | ||
169 | { | ||
170 | return m_UserService.CreateUserAccount(data); | ||
171 | } | ||
172 | |||
173 | #endregion | ||
174 | |||
130 | } | 175 | } |
131 | } | 176 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/User/RemoteUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs index cef9129..d322aba 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/User/RemoteUserServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs | |||
@@ -34,9 +34,9 @@ using OpenSim.Region.Framework.Scenes; | |||
34 | using OpenSim.Services.Interfaces; | 34 | using OpenSim.Services.Interfaces; |
35 | using OpenSim.Services.Connectors; | 35 | using OpenSim.Services.Connectors; |
36 | 36 | ||
37 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | 37 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts |
38 | { | 38 | { |
39 | public class RemoteUserServicesConnector : UserServicesConnector, | 39 | public class RemoteUserAccountServicesConnector : UserAccountServicesConnector, |
40 | ISharedRegionModule, IUserAccountService | 40 | ISharedRegionModule, IUserAccountService |
41 | { | 41 | { |
42 | private static readonly ILog m_log = | 42 | private static readonly ILog m_log = |
@@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.User | |||
52 | 52 | ||
53 | public string Name | 53 | public string Name |
54 | { | 54 | { |
55 | get { return "RemoteUserServicesConnector"; } | 55 | get { return "RemoteUserAccountServicesConnector"; } |
56 | } | 56 | } |
57 | 57 | ||
58 | public override void Initialise(IConfigSource source) | 58 | public override void Initialise(IConfigSource source) |
diff --git a/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs b/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs index 630c6a3..d44c1e1 100644 --- a/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs | |||
@@ -31,13 +31,13 @@ namespace OpenSim.Region.Framework.Interfaces | |||
31 | { | 31 | { |
32 | public struct PresenceInfo | 32 | public struct PresenceInfo |
33 | { | 33 | { |
34 | public UUID userID; | 34 | public string UserID; |
35 | public UUID regionID; | 35 | public UUID RegionID; |
36 | 36 | ||
37 | public PresenceInfo(UUID userID, UUID regionID) | 37 | public PresenceInfo(string userID, UUID regionID) |
38 | { | 38 | { |
39 | this.userID = userID; | 39 | UserID = userID; |
40 | this.regionID = regionID; | 40 | RegionID = regionID; |
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 0964caa..a5d28a4 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs | |||
@@ -160,9 +160,9 @@ namespace OpenSim.Server.Base | |||
160 | } | 160 | } |
161 | } | 161 | } |
162 | 162 | ||
163 | public static Dictionary<string, string> ParseQueryString(string query) | 163 | public static Dictionary<string, object> ParseQueryString(string query) |
164 | { | 164 | { |
165 | Dictionary<string, string> result = new Dictionary<string, string>(); | 165 | Dictionary<string, object> result = new Dictionary<string, object>(); |
166 | string[] terms = query.Split(new char[] {'&'}); | 166 | string[] terms = query.Split(new char[] {'&'}); |
167 | 167 | ||
168 | if (terms.Length == 0) | 168 | if (terms.Length == 0) |
@@ -180,33 +180,76 @@ namespace OpenSim.Server.Base | |||
180 | if (elems.Length > 1) | 180 | if (elems.Length > 1) |
181 | value = System.Web.HttpUtility.UrlDecode(elems[1]); | 181 | value = System.Web.HttpUtility.UrlDecode(elems[1]); |
182 | 182 | ||
183 | result[name] = value; | 183 | if (name.EndsWith("[]")) |
184 | { | ||
185 | if (result.ContainsKey(name)) | ||
186 | { | ||
187 | if (!(result[name] is List<string>)) | ||
188 | continue; | ||
189 | |||
190 | List<string> l = (List<string>)result[name]; | ||
191 | |||
192 | l.Add(value); | ||
193 | } | ||
194 | else | ||
195 | { | ||
196 | List<string> newList = new List<string>(); | ||
197 | |||
198 | newList.Add(value); | ||
199 | |||
200 | result[name] = newList; | ||
201 | } | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | if (!result.ContainsKey(name)) | ||
206 | result[name] = value; | ||
207 | } | ||
184 | } | 208 | } |
185 | 209 | ||
186 | return result; | 210 | return result; |
187 | } | 211 | } |
188 | 212 | ||
189 | public static string BuildQueryString(Dictionary<string, string> data) | 213 | public static string BuildQueryString(Dictionary<string, object> data) |
190 | { | 214 | { |
191 | string qstring = String.Empty; | 215 | string qstring = String.Empty; |
192 | 216 | ||
193 | foreach (KeyValuePair<string, string> kvp in data) | 217 | string part; |
218 | |||
219 | foreach (KeyValuePair<string, object> kvp in data) | ||
194 | { | 220 | { |
195 | string part; | 221 | if (kvp.Value is List<string>) |
196 | if (kvp.Value != String.Empty) | ||
197 | { | 222 | { |
198 | part = System.Web.HttpUtility.UrlEncode(kvp.Key) + | 223 | List<string> l = (List<String>)kvp.Value; |
199 | "=" + System.Web.HttpUtility.UrlEncode(kvp.Value); | 224 | |
225 | foreach (string s in l) | ||
226 | { | ||
227 | part = System.Web.HttpUtility.UrlEncode(kvp.Key) + | ||
228 | "[]=" + System.Web.HttpUtility.UrlEncode(s); | ||
229 | |||
230 | if (qstring != String.Empty) | ||
231 | qstring += "&"; | ||
232 | |||
233 | qstring += part; | ||
234 | } | ||
200 | } | 235 | } |
201 | else | 236 | else |
202 | { | 237 | { |
203 | part = System.Web.HttpUtility.UrlEncode(kvp.Key); | 238 | if (kvp.Value.ToString() != String.Empty) |
204 | } | 239 | { |
240 | part = System.Web.HttpUtility.UrlEncode(kvp.Key) + | ||
241 | "=" + System.Web.HttpUtility.UrlEncode(kvp.Value.ToString()); | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | part = System.Web.HttpUtility.UrlEncode(kvp.Key); | ||
246 | } | ||
205 | 247 | ||
206 | if (qstring != String.Empty) | 248 | if (qstring != String.Empty) |
207 | qstring += "&"; | 249 | qstring += "&"; |
208 | 250 | ||
209 | qstring += part; | 251 | qstring += part; |
252 | } | ||
210 | } | 253 | } |
211 | 254 | ||
212 | return qstring; | 255 | return qstring; |
diff --git a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs index 490a13a..47bc860 100644 --- a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs | |||
@@ -86,14 +86,14 @@ namespace OpenSim.Server.Handlers.Authentication | |||
86 | 86 | ||
87 | private byte[] DoPlainMethods(string body) | 87 | private byte[] DoPlainMethods(string body) |
88 | { | 88 | { |
89 | Dictionary<string, string> request = | 89 | Dictionary<string, object> request = |
90 | ServerUtils.ParseQueryString(body); | 90 | ServerUtils.ParseQueryString(body); |
91 | 91 | ||
92 | int lifetime = 30; | 92 | int lifetime = 30; |
93 | 93 | ||
94 | if (request.ContainsKey("LIFETIME")) | 94 | if (request.ContainsKey("LIFETIME")) |
95 | { | 95 | { |
96 | lifetime = Convert.ToInt32(request["LIFETIME"]); | 96 | lifetime = Convert.ToInt32(request["LIFETIME"].ToString()); |
97 | if (lifetime > 30) | 97 | if (lifetime > 30) |
98 | lifetime = 30; | 98 | lifetime = 30; |
99 | } | 99 | } |
@@ -103,12 +103,12 @@ namespace OpenSim.Server.Handlers.Authentication | |||
103 | if (!request.ContainsKey("PRINCIPAL")) | 103 | if (!request.ContainsKey("PRINCIPAL")) |
104 | return FailureResult(); | 104 | return FailureResult(); |
105 | 105 | ||
106 | string method = request["METHOD"]; | 106 | string method = request["METHOD"].ToString(); |
107 | 107 | ||
108 | UUID principalID; | 108 | UUID principalID; |
109 | string token; | 109 | string token; |
110 | 110 | ||
111 | if (!UUID.TryParse(request["PRINCIPAL"], out principalID)) | 111 | if (!UUID.TryParse(request["PRINCIPAL"].ToString(), out principalID)) |
112 | return FailureResult(); | 112 | return FailureResult(); |
113 | 113 | ||
114 | switch (method) | 114 | switch (method) |
@@ -117,7 +117,7 @@ namespace OpenSim.Server.Handlers.Authentication | |||
117 | if (!request.ContainsKey("PASSWORD")) | 117 | if (!request.ContainsKey("PASSWORD")) |
118 | return FailureResult(); | 118 | return FailureResult(); |
119 | 119 | ||
120 | token = m_AuthenticationService.Authenticate(principalID, request["PASSWORD"], lifetime); | 120 | token = m_AuthenticationService.Authenticate(principalID, request["PASSWORD"].ToString(), lifetime); |
121 | 121 | ||
122 | if (token != String.Empty) | 122 | if (token != String.Empty) |
123 | return SuccessResult(token); | 123 | return SuccessResult(token); |
@@ -126,7 +126,7 @@ namespace OpenSim.Server.Handlers.Authentication | |||
126 | if (!request.ContainsKey("TOKEN")) | 126 | if (!request.ContainsKey("TOKEN")) |
127 | return FailureResult(); | 127 | return FailureResult(); |
128 | 128 | ||
129 | if (m_AuthenticationService.Verify(principalID, request["TOKEN"], lifetime)) | 129 | if (m_AuthenticationService.Verify(principalID, request["TOKEN"].ToString(), lifetime)) |
130 | return SuccessResult(); | 130 | return SuccessResult(); |
131 | 131 | ||
132 | return FailureResult(); | 132 | return FailureResult(); |
@@ -134,7 +134,7 @@ namespace OpenSim.Server.Handlers.Authentication | |||
134 | if (!request.ContainsKey("TOKEN")) | 134 | if (!request.ContainsKey("TOKEN")) |
135 | return FailureResult(); | 135 | return FailureResult(); |
136 | 136 | ||
137 | if (m_AuthenticationService.Release(principalID, request["TOKEN"])) | 137 | if (m_AuthenticationService.Release(principalID, request["TOKEN"].ToString())) |
138 | return SuccessResult(); | 138 | return SuccessResult(); |
139 | 139 | ||
140 | return FailureResult(); | 140 | return FailureResult(); |
diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index 433ed0b..d99b791 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs | |||
@@ -69,13 +69,13 @@ namespace OpenSim.Server.Handlers.Grid | |||
69 | 69 | ||
70 | try | 70 | try |
71 | { | 71 | { |
72 | Dictionary<string, string> request = | 72 | Dictionary<string, object> request = |
73 | ServerUtils.ParseQueryString(body); | 73 | ServerUtils.ParseQueryString(body); |
74 | 74 | ||
75 | if (!request.ContainsKey("METHOD")) | 75 | if (!request.ContainsKey("METHOD")) |
76 | return FailureResult(); | 76 | return FailureResult(); |
77 | 77 | ||
78 | string method = request["METHOD"]; | 78 | string method = request["METHOD"].ToString(); |
79 | 79 | ||
80 | switch (method) | 80 | switch (method) |
81 | { | 81 | { |
@@ -117,22 +117,22 @@ namespace OpenSim.Server.Handlers.Grid | |||
117 | 117 | ||
118 | #region Method-specific handlers | 118 | #region Method-specific handlers |
119 | 119 | ||
120 | byte[] Register(Dictionary<string, string> request) | 120 | byte[] Register(Dictionary<string, object> request) |
121 | { | 121 | { |
122 | UUID scopeID = UUID.Zero; | 122 | UUID scopeID = UUID.Zero; |
123 | if (request.ContainsKey("SCOPEID")) | 123 | if (request.ContainsKey("SCOPEID")) |
124 | UUID.TryParse(request["SCOPEID"], out scopeID); | 124 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
125 | else | 125 | else |
126 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to register region"); | 126 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to register region"); |
127 | 127 | ||
128 | int versionNumberMin = 0, versionNumberMax = 0; | 128 | int versionNumberMin = 0, versionNumberMax = 0; |
129 | if (request.ContainsKey("VERSIONMIN")) | 129 | if (request.ContainsKey("VERSIONMIN")) |
130 | Int32.TryParse(request["VERSIONMIN"], out versionNumberMin); | 130 | Int32.TryParse(request["VERSIONMIN"].ToString(), out versionNumberMin); |
131 | else | 131 | else |
132 | m_log.WarnFormat("[GRID HANDLER]: no minimum protocol version in request to register region"); | 132 | m_log.WarnFormat("[GRID HANDLER]: no minimum protocol version in request to register region"); |
133 | 133 | ||
134 | if (request.ContainsKey("VERSIONMAX")) | 134 | if (request.ContainsKey("VERSIONMAX")) |
135 | Int32.TryParse(request["VERSIONMAX"], out versionNumberMax); | 135 | Int32.TryParse(request["VERSIONMAX"].ToString(), out versionNumberMax); |
136 | else | 136 | else |
137 | m_log.WarnFormat("[GRID HANDLER]: no maximum protocol version in request to register region"); | 137 | m_log.WarnFormat("[GRID HANDLER]: no maximum protocol version in request to register region"); |
138 | 138 | ||
@@ -147,8 +147,8 @@ namespace OpenSim.Server.Handlers.Grid | |||
147 | GridRegion rinfo = null; | 147 | GridRegion rinfo = null; |
148 | try | 148 | try |
149 | { | 149 | { |
150 | foreach (KeyValuePair<string, string> kvp in request) | 150 | foreach (KeyValuePair<string, object> kvp in request) |
151 | rinfoData[kvp.Key] = kvp.Value; | 151 | rinfoData[kvp.Key] = kvp.Value.ToString(); |
152 | rinfo = new GridRegion(rinfoData); | 152 | rinfo = new GridRegion(rinfoData); |
153 | } | 153 | } |
154 | catch (Exception e) | 154 | catch (Exception e) |
@@ -166,11 +166,11 @@ namespace OpenSim.Server.Handlers.Grid | |||
166 | return FailureResult(); | 166 | return FailureResult(); |
167 | } | 167 | } |
168 | 168 | ||
169 | byte[] Deregister(Dictionary<string, string> request) | 169 | byte[] Deregister(Dictionary<string, object> request) |
170 | { | 170 | { |
171 | UUID regionID = UUID.Zero; | 171 | UUID regionID = UUID.Zero; |
172 | if (request["REGIONID"] != null) | 172 | if (request.ContainsKey("REGIONID")) |
173 | UUID.TryParse(request["REGIONID"], out regionID); | 173 | UUID.TryParse(request["REGIONID"].ToString(), out regionID); |
174 | else | 174 | else |
175 | m_log.WarnFormat("[GRID HANDLER]: no regionID in request to deregister region"); | 175 | m_log.WarnFormat("[GRID HANDLER]: no regionID in request to deregister region"); |
176 | 176 | ||
@@ -183,17 +183,17 @@ namespace OpenSim.Server.Handlers.Grid | |||
183 | 183 | ||
184 | } | 184 | } |
185 | 185 | ||
186 | byte[] GetNeighbours(Dictionary<string, string> request) | 186 | byte[] GetNeighbours(Dictionary<string, object> request) |
187 | { | 187 | { |
188 | UUID scopeID = UUID.Zero; | 188 | UUID scopeID = UUID.Zero; |
189 | if (request["SCOPEID"] != null) | 189 | if (request.ContainsKey("SCOPEID")) |
190 | UUID.TryParse(request["SCOPEID"], out scopeID); | 190 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
191 | else | 191 | else |
192 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get neighbours"); | 192 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get neighbours"); |
193 | 193 | ||
194 | UUID regionID = UUID.Zero; | 194 | UUID regionID = UUID.Zero; |
195 | if (request["REGIONID"] != null) | 195 | if (request.ContainsKey("REGIONID")) |
196 | UUID.TryParse(request["REGIONID"], out regionID); | 196 | UUID.TryParse(request["REGIONID"].ToString(), out regionID); |
197 | else | 197 | else |
198 | m_log.WarnFormat("[GRID HANDLER]: no regionID in request to get neighbours"); | 198 | m_log.WarnFormat("[GRID HANDLER]: no regionID in request to get neighbours"); |
199 | 199 | ||
@@ -221,17 +221,17 @@ namespace OpenSim.Server.Handlers.Grid | |||
221 | 221 | ||
222 | } | 222 | } |
223 | 223 | ||
224 | byte[] GetRegionByUUID(Dictionary<string, string> request) | 224 | byte[] GetRegionByUUID(Dictionary<string, object> request) |
225 | { | 225 | { |
226 | UUID scopeID = UUID.Zero; | 226 | UUID scopeID = UUID.Zero; |
227 | if (request["SCOPEID"] != null) | 227 | if (request.ContainsKey("SCOPEID")) |
228 | UUID.TryParse(request["SCOPEID"], out scopeID); | 228 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
229 | else | 229 | else |
230 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get neighbours"); | 230 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get neighbours"); |
231 | 231 | ||
232 | UUID regionID = UUID.Zero; | 232 | UUID regionID = UUID.Zero; |
233 | if (request["REGIONID"] != null) | 233 | if (request.ContainsKey("REGIONID")) |
234 | UUID.TryParse(request["REGIONID"], out regionID); | 234 | UUID.TryParse(request["REGIONID"].ToString(), out regionID); |
235 | else | 235 | else |
236 | m_log.WarnFormat("[GRID HANDLER]: no regionID in request to get neighbours"); | 236 | m_log.WarnFormat("[GRID HANDLER]: no regionID in request to get neighbours"); |
237 | 237 | ||
@@ -250,21 +250,21 @@ namespace OpenSim.Server.Handlers.Grid | |||
250 | return encoding.GetBytes(xmlString); | 250 | return encoding.GetBytes(xmlString); |
251 | } | 251 | } |
252 | 252 | ||
253 | byte[] GetRegionByPosition(Dictionary<string, string> request) | 253 | byte[] GetRegionByPosition(Dictionary<string, object> request) |
254 | { | 254 | { |
255 | UUID scopeID = UUID.Zero; | 255 | UUID scopeID = UUID.Zero; |
256 | if (request["SCOPEID"] != null) | 256 | if (request.ContainsKey("SCOPEID")) |
257 | UUID.TryParse(request["SCOPEID"], out scopeID); | 257 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
258 | else | 258 | else |
259 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region by position"); | 259 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region by position"); |
260 | 260 | ||
261 | int x = 0, y = 0; | 261 | int x = 0, y = 0; |
262 | if (request["X"] != null) | 262 | if (request.ContainsKey("X")) |
263 | Int32.TryParse(request["X"], out x); | 263 | Int32.TryParse(request["X"].ToString(), out x); |
264 | else | 264 | else |
265 | m_log.WarnFormat("[GRID HANDLER]: no X in request to get region by position"); | 265 | m_log.WarnFormat("[GRID HANDLER]: no X in request to get region by position"); |
266 | if (request["Y"] != null) | 266 | if (request.ContainsKey("Y")) |
267 | Int32.TryParse(request["Y"], out y); | 267 | Int32.TryParse(request["Y"].ToString(), out y); |
268 | else | 268 | else |
269 | m_log.WarnFormat("[GRID HANDLER]: no Y in request to get region by position"); | 269 | m_log.WarnFormat("[GRID HANDLER]: no Y in request to get region by position"); |
270 | 270 | ||
@@ -283,17 +283,17 @@ namespace OpenSim.Server.Handlers.Grid | |||
283 | return encoding.GetBytes(xmlString); | 283 | return encoding.GetBytes(xmlString); |
284 | } | 284 | } |
285 | 285 | ||
286 | byte[] GetRegionByName(Dictionary<string, string> request) | 286 | byte[] GetRegionByName(Dictionary<string, object> request) |
287 | { | 287 | { |
288 | UUID scopeID = UUID.Zero; | 288 | UUID scopeID = UUID.Zero; |
289 | if (request["SCOPEID"] != null) | 289 | if (request.ContainsKey("SCOPEID")) |
290 | UUID.TryParse(request["SCOPEID"], out scopeID); | 290 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
291 | else | 291 | else |
292 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region by name"); | 292 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region by name"); |
293 | 293 | ||
294 | string regionName = string.Empty; | 294 | string regionName = string.Empty; |
295 | if (request["NAME"] != null) | 295 | if (request.ContainsKey("NAME")) |
296 | regionName = request["NAME"]; | 296 | regionName = request["NAME"].ToString(); |
297 | else | 297 | else |
298 | m_log.WarnFormat("[GRID HANDLER]: no name in request to get region by name"); | 298 | m_log.WarnFormat("[GRID HANDLER]: no name in request to get region by name"); |
299 | 299 | ||
@@ -312,23 +312,23 @@ namespace OpenSim.Server.Handlers.Grid | |||
312 | return encoding.GetBytes(xmlString); | 312 | return encoding.GetBytes(xmlString); |
313 | } | 313 | } |
314 | 314 | ||
315 | byte[] GetRegionsByName(Dictionary<string, string> request) | 315 | byte[] GetRegionsByName(Dictionary<string, object> request) |
316 | { | 316 | { |
317 | UUID scopeID = UUID.Zero; | 317 | UUID scopeID = UUID.Zero; |
318 | if (request["SCOPEID"] != null) | 318 | if (request.ContainsKey("SCOPEID")) |
319 | UUID.TryParse(request["SCOPEID"], out scopeID); | 319 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
320 | else | 320 | else |
321 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get regions by name"); | 321 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get regions by name"); |
322 | 322 | ||
323 | string regionName = string.Empty; | 323 | string regionName = string.Empty; |
324 | if (request["NAME"] != null) | 324 | if (request.ContainsKey("NAME")) |
325 | regionName = request["NAME"]; | 325 | regionName = request["NAME"].ToString(); |
326 | else | 326 | else |
327 | m_log.WarnFormat("[GRID HANDLER]: no NAME in request to get regions by name"); | 327 | m_log.WarnFormat("[GRID HANDLER]: no NAME in request to get regions by name"); |
328 | 328 | ||
329 | int max = 0; | 329 | int max = 0; |
330 | if (request["MAX"] != null) | 330 | if (request.ContainsKey("MAX")) |
331 | Int32.TryParse(request["MAX"], out max); | 331 | Int32.TryParse(request["MAX"].ToString(), out max); |
332 | else | 332 | else |
333 | m_log.WarnFormat("[GRID HANDLER]: no MAX in request to get regions by name"); | 333 | m_log.WarnFormat("[GRID HANDLER]: no MAX in request to get regions by name"); |
334 | 334 | ||
@@ -355,30 +355,30 @@ namespace OpenSim.Server.Handlers.Grid | |||
355 | return encoding.GetBytes(xmlString); | 355 | return encoding.GetBytes(xmlString); |
356 | } | 356 | } |
357 | 357 | ||
358 | byte[] GetRegionRange(Dictionary<string, string> request) | 358 | byte[] GetRegionRange(Dictionary<string, object> request) |
359 | { | 359 | { |
360 | //m_log.DebugFormat("[GRID HANDLER]: GetRegionRange"); | 360 | //m_log.DebugFormat("[GRID HANDLER]: GetRegionRange"); |
361 | UUID scopeID = UUID.Zero; | 361 | UUID scopeID = UUID.Zero; |
362 | if (request.ContainsKey("SCOPEID")) | 362 | if (request.ContainsKey("SCOPEID")) |
363 | UUID.TryParse(request["SCOPEID"], out scopeID); | 363 | UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); |
364 | else | 364 | else |
365 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region range"); | 365 | m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region range"); |
366 | 366 | ||
367 | int xmin = 0, xmax = 0, ymin = 0, ymax = 0; | 367 | int xmin = 0, xmax = 0, ymin = 0, ymax = 0; |
368 | if (request.ContainsKey("XMIN")) | 368 | if (request.ContainsKey("XMIN")) |
369 | Int32.TryParse(request["XMIN"], out xmin); | 369 | Int32.TryParse(request["XMIN"].ToString(), out xmin); |
370 | else | 370 | else |
371 | m_log.WarnFormat("[GRID HANDLER]: no XMIN in request to get region range"); | 371 | m_log.WarnFormat("[GRID HANDLER]: no XMIN in request to get region range"); |
372 | if (request.ContainsKey("XMAX")) | 372 | if (request.ContainsKey("XMAX")) |
373 | Int32.TryParse(request["XMAX"], out xmax); | 373 | Int32.TryParse(request["XMAX"].ToString(), out xmax); |
374 | else | 374 | else |
375 | m_log.WarnFormat("[GRID HANDLER]: no XMAX in request to get region range"); | 375 | m_log.WarnFormat("[GRID HANDLER]: no XMAX in request to get region range"); |
376 | if (request.ContainsKey("YMIN")) | 376 | if (request.ContainsKey("YMIN")) |
377 | Int32.TryParse(request["YMIN"], out ymin); | 377 | Int32.TryParse(request["YMIN"].ToString(), out ymin); |
378 | else | 378 | else |
379 | m_log.WarnFormat("[GRID HANDLER]: no YMIN in request to get region range"); | 379 | m_log.WarnFormat("[GRID HANDLER]: no YMIN in request to get region range"); |
380 | if (request.ContainsKey("YMAX")) | 380 | if (request.ContainsKey("YMAX")) |
381 | Int32.TryParse(request["YMAX"], out ymax); | 381 | Int32.TryParse(request["YMAX"].ToString(), out ymax); |
382 | else | 382 | else |
383 | m_log.WarnFormat("[GRID HANDLER]: no YMAX in request to get region range"); | 383 | m_log.WarnFormat("[GRID HANDLER]: no YMAX in request to get region range"); |
384 | 384 | ||
diff --git a/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs b/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs index 2558fa0..11adc4a 100644 --- a/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs | |||
@@ -68,18 +68,30 @@ namespace OpenSim.Server.Handlers.Presence | |||
68 | 68 | ||
69 | try | 69 | try |
70 | { | 70 | { |
71 | Dictionary<string, string> request = | 71 | Dictionary<string, object> request = |
72 | ServerUtils.ParseQueryString(body); | 72 | ServerUtils.ParseQueryString(body); |
73 | 73 | ||
74 | if (!request.ContainsKey("METHOD")) | 74 | if (!request.ContainsKey("METHOD")) |
75 | return FailureResult(); | 75 | return FailureResult(); |
76 | 76 | ||
77 | string method = request["METHOD"]; | 77 | string method = request["METHOD"].ToString(); |
78 | 78 | ||
79 | switch (method) | 79 | switch (method) |
80 | { | 80 | { |
81 | case "login": | ||
82 | return LoginAgent(request); | ||
83 | case "logout": | ||
84 | return LogoutAgent(request); | ||
85 | case "logoutregion": | ||
86 | return LogoutRegionAgents(request); | ||
81 | case "report": | 87 | case "report": |
82 | return Report(request); | 88 | return Report(request); |
89 | case "getagent": | ||
90 | return GetAgent(request); | ||
91 | case "getagents": | ||
92 | return GetAgents(request); | ||
93 | case "sethome": | ||
94 | return SetHome(request); | ||
83 | } | 95 | } |
84 | m_log.DebugFormat("[PRESENCE HANDLER]: unknown method request: {0}", method); | 96 | m_log.DebugFormat("[PRESENCE HANDLER]: unknown method request: {0}", method); |
85 | } | 97 | } |
@@ -92,38 +104,153 @@ namespace OpenSim.Server.Handlers.Presence | |||
92 | 104 | ||
93 | } | 105 | } |
94 | 106 | ||
95 | byte[] Report(Dictionary<string, string> request) | 107 | byte[] LoginAgent(Dictionary<string, object> request) |
96 | { | 108 | { |
97 | PresenceInfo info = new PresenceInfo(); | 109 | string user = String.Empty; |
98 | info.Data = new Dictionary<string, string>(); | 110 | UUID session = UUID.Zero; |
111 | UUID ssession = UUID.Zero; | ||
99 | 112 | ||
100 | if (request["PrincipalID"] == null || request["RegionID"] == null) | 113 | if (!request.ContainsKey("UserID") || !request.ContainsKey("SessionID")) |
101 | return FailureResult(); | 114 | return FailureResult(); |
102 | 115 | ||
103 | if (!UUID.TryParse(request["PrincipalID"].ToString(), | 116 | user = request["UserID"].ToString(); |
104 | out info.PrincipalID)) | 117 | |
118 | if (!UUID.TryParse(request["SessionID"].ToString(), out session)) | ||
105 | return FailureResult(); | 119 | return FailureResult(); |
106 | 120 | ||
107 | if (!UUID.TryParse(request["RegionID"].ToString(), | 121 | if (request.ContainsKey("SecureSessionID")) |
108 | out info.RegionID)) | 122 | // If it's malformed, we go on with a Zero on it |
123 | UUID.TryParse(request["SecureSessionID"].ToString(), out ssession); | ||
124 | |||
125 | if (m_PresenceService.LoginAgent(user, session, ssession)) | ||
126 | return SuccessResult(); | ||
127 | |||
128 | return FailureResult(); | ||
129 | } | ||
130 | |||
131 | byte[] LogoutAgent(Dictionary<string, object> request) | ||
132 | { | ||
133 | UUID session = UUID.Zero; | ||
134 | |||
135 | if (!request.ContainsKey("SessionID")) | ||
109 | return FailureResult(); | 136 | return FailureResult(); |
110 | 137 | ||
111 | foreach (KeyValuePair<string, string> kvp in request) | 138 | if (!UUID.TryParse(request["SessionID"].ToString(), out session)) |
112 | { | 139 | return FailureResult(); |
113 | if (kvp.Key == "METHOD" || | ||
114 | kvp.Key == "PrincipalID" || | ||
115 | kvp.Key == "RegionID") | ||
116 | continue; | ||
117 | 140 | ||
118 | info.Data[kvp.Key] = kvp.Value; | 141 | if (m_PresenceService.LogoutAgent(session)) |
119 | } | 142 | return SuccessResult(); |
143 | |||
144 | return FailureResult(); | ||
145 | } | ||
146 | |||
147 | byte[] LogoutRegionAgents(Dictionary<string, object> request) | ||
148 | { | ||
149 | UUID region = UUID.Zero; | ||
150 | |||
151 | if (!request.ContainsKey("RegionID")) | ||
152 | return FailureResult(); | ||
120 | 153 | ||
121 | if (m_PresenceService.Report(info)) | 154 | if (!UUID.TryParse(request["RegionID"].ToString(), out region)) |
155 | return FailureResult(); | ||
156 | |||
157 | if (m_PresenceService.LogoutRegionAgents(region)) | ||
122 | return SuccessResult(); | 158 | return SuccessResult(); |
123 | 159 | ||
124 | return FailureResult(); | 160 | return FailureResult(); |
125 | } | 161 | } |
162 | |||
163 | byte[] Report(Dictionary<string, object> request) | ||
164 | { | ||
165 | UUID session = UUID.Zero; | ||
166 | UUID region = UUID.Zero; | ||
167 | Vector3 position = new Vector3(128, 128, 70); | ||
168 | Vector3 look = Vector3.Zero; | ||
169 | |||
170 | if (!request.ContainsKey("SessionID") || !request.ContainsKey("RegionID")) | ||
171 | return FailureResult(); | ||
172 | |||
173 | if (!UUID.TryParse(request["SessionID"].ToString(), out session)) | ||
174 | return FailureResult(); | ||
175 | |||
176 | if (!UUID.TryParse(request["RegionID"].ToString(), out region)) | ||
177 | return FailureResult(); | ||
178 | |||
179 | if (request.ContainsKey("position")) | ||
180 | Vector3.TryParse(request["position"].ToString(), out position); | ||
181 | |||
182 | if (request.ContainsKey("lookAt")) | ||
183 | Vector3.TryParse(request["lookAt"].ToString(), out look); | ||
184 | |||
185 | if (m_PresenceService.ReportAgent(session, region, position, look)) | ||
186 | return SuccessResult(); | ||
187 | |||
188 | return FailureResult(); | ||
189 | } | ||
190 | |||
191 | byte[] GetAgent(Dictionary<string, object> request) | ||
192 | { | ||
193 | UUID session = UUID.Zero; | ||
194 | |||
195 | if (!request.ContainsKey("SessionID")) | ||
196 | return FailureResult(); | ||
126 | 197 | ||
198 | if (!UUID.TryParse(request["SessionID"].ToString(), out session)) | ||
199 | return FailureResult(); | ||
200 | |||
201 | PresenceInfo pinfo = m_PresenceService.GetAgent(session); | ||
202 | |||
203 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
204 | if (pinfo == null) | ||
205 | result["result"] = "null"; | ||
206 | else | ||
207 | result["result"] = pinfo.ToKeyValuePairs(); | ||
208 | |||
209 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
210 | //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); | ||
211 | UTF8Encoding encoding = new UTF8Encoding(); | ||
212 | return encoding.GetBytes(xmlString); | ||
213 | } | ||
214 | |||
215 | byte[] GetAgents(Dictionary<string, object> request) | ||
216 | { | ||
217 | |||
218 | string[] userIDs; | ||
219 | |||
220 | if (!request.ContainsKey("uuids")) | ||
221 | return FailureResult(); | ||
222 | |||
223 | if (!(request["uuids"] is List<string>)) | ||
224 | { | ||
225 | m_log.DebugFormat("[PRESENCE HANDLER]: GetAgents input argument was of unexpected type {0}", request["uuids"].GetType().ToString()); | ||
226 | return FailureResult(); | ||
227 | } | ||
228 | |||
229 | userIDs = ((List<string>)request["uuids"]).ToArray(); | ||
230 | |||
231 | PresenceInfo[] pinfos = m_PresenceService.GetAgents(userIDs); | ||
232 | |||
233 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
234 | if ((pinfos == null) || ((pinfos != null) && (pinfos.Length == 0))) | ||
235 | result["result"] = "null"; | ||
236 | else | ||
237 | { | ||
238 | int i = 0; | ||
239 | foreach (PresenceInfo pinfo in pinfos) | ||
240 | { | ||
241 | Dictionary<string, object> rinfoDict = pinfo.ToKeyValuePairs(); | ||
242 | result["presence" + i] = rinfoDict; | ||
243 | i++; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
248 | //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); | ||
249 | UTF8Encoding encoding = new UTF8Encoding(); | ||
250 | return encoding.GetBytes(xmlString); | ||
251 | } | ||
252 | |||
253 | |||
127 | private byte[] SuccessResult() | 254 | private byte[] SuccessResult() |
128 | { | 255 | { |
129 | XmlDocument doc = new XmlDocument(); | 256 | XmlDocument doc = new XmlDocument(); |
@@ -138,7 +265,7 @@ namespace OpenSim.Server.Handlers.Presence | |||
138 | 265 | ||
139 | doc.AppendChild(rootElement); | 266 | doc.AppendChild(rootElement); |
140 | 267 | ||
141 | XmlElement result = doc.CreateElement("", "Result", ""); | 268 | XmlElement result = doc.CreateElement("", "result", ""); |
142 | result.AppendChild(doc.CreateTextNode("Success")); | 269 | result.AppendChild(doc.CreateTextNode("Success")); |
143 | 270 | ||
144 | rootElement.AppendChild(result); | 271 | rootElement.AppendChild(result); |
@@ -160,7 +287,7 @@ namespace OpenSim.Server.Handlers.Presence | |||
160 | 287 | ||
161 | doc.AppendChild(rootElement); | 288 | doc.AppendChild(rootElement); |
162 | 289 | ||
163 | XmlElement result = doc.CreateElement("", "Result", ""); | 290 | XmlElement result = doc.CreateElement("", "result", ""); |
164 | result.AppendChild(doc.CreateTextNode("Failure")); | 291 | result.AppendChild(doc.CreateTextNode("Failure")); |
165 | 292 | ||
166 | rootElement.AppendChild(result); | 293 | rootElement.AppendChild(result); |
@@ -178,5 +305,32 @@ namespace OpenSim.Server.Handlers.Presence | |||
178 | 305 | ||
179 | return ms.ToArray(); | 306 | return ms.ToArray(); |
180 | } | 307 | } |
308 | |||
309 | byte[] SetHome(Dictionary<string, object> request) | ||
310 | { | ||
311 | UUID region = UUID.Zero; | ||
312 | Vector3 position = new Vector3(128, 128, 70); | ||
313 | Vector3 look = Vector3.Zero; | ||
314 | |||
315 | if (!request.ContainsKey("SessionID") || !request.ContainsKey("RegionID")) | ||
316 | return FailureResult(); | ||
317 | |||
318 | string user = request["UserID"].ToString(); | ||
319 | |||
320 | if (!UUID.TryParse(request["RegionID"].ToString(), out region)) | ||
321 | return FailureResult(); | ||
322 | |||
323 | if (request.ContainsKey("position")) | ||
324 | Vector3.TryParse(request["position"].ToString(), out position); | ||
325 | |||
326 | if (request.ContainsKey("lookAt")) | ||
327 | Vector3.TryParse(request["lookAt"].ToString(), out look); | ||
328 | |||
329 | if (m_PresenceService.SetHomeLocation(user, region, position, look)) | ||
330 | return SuccessResult(); | ||
331 | |||
332 | return FailureResult(); | ||
333 | } | ||
334 | |||
181 | } | 335 | } |
182 | } | 336 | } |
diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerConnector.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerConnector.cs new file mode 100644 index 0000000..f17a8de --- /dev/null +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerConnector.cs | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using Nini.Config; | ||
30 | using OpenSim.Server.Base; | ||
31 | using OpenSim.Services.Interfaces; | ||
32 | using OpenSim.Framework.Servers.HttpServer; | ||
33 | using OpenSim.Server.Handlers.Base; | ||
34 | |||
35 | namespace OpenSim.Server.Handlers.UserAccounts | ||
36 | { | ||
37 | public class UserAccountServiceConnector : ServiceConnector | ||
38 | { | ||
39 | private IUserAccountService m_UserAccountService; | ||
40 | private string m_ConfigName = "UserAccountService"; | ||
41 | |||
42 | public UserAccountServiceConnector(IConfigSource config, IHttpServer server, string configName) : | ||
43 | base(config, server, configName) | ||
44 | { | ||
45 | IConfig serverConfig = config.Configs[m_ConfigName]; | ||
46 | if (serverConfig == null) | ||
47 | throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); | ||
48 | |||
49 | string service = serverConfig.GetString("LocalServiceModule", | ||
50 | String.Empty); | ||
51 | |||
52 | if (service == String.Empty) | ||
53 | throw new Exception("No LocalServiceModule in config file"); | ||
54 | |||
55 | Object[] args = new Object[] { config }; | ||
56 | m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(service, args); | ||
57 | |||
58 | server.AddStreamHandler(new UserAccountServerPostHandler(m_UserAccountService)); | ||
59 | } | ||
60 | } | ||
61 | } | ||
diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs new file mode 100644 index 0000000..a92148c --- /dev/null +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using Nini.Config; | ||
29 | using log4net; | ||
30 | using System; | ||
31 | using System.Reflection; | ||
32 | using System.IO; | ||
33 | using System.Net; | ||
34 | using System.Text; | ||
35 | using System.Text.RegularExpressions; | ||
36 | using System.Xml; | ||
37 | using System.Xml.Serialization; | ||
38 | using System.Collections.Generic; | ||
39 | using OpenSim.Server.Base; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using OpenSim.Framework; | ||
42 | using OpenSim.Framework.Servers.HttpServer; | ||
43 | using OpenMetaverse; | ||
44 | |||
45 | namespace OpenSim.Server.Handlers.UserAccounts | ||
46 | { | ||
47 | public class UserAccountServerPostHandler : BaseStreamHandler | ||
48 | { | ||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | private IUserAccountService m_UserAccountService; | ||
52 | |||
53 | public UserAccountServerPostHandler(IUserAccountService service) : | ||
54 | base("POST", "/accounts") | ||
55 | { | ||
56 | m_UserAccountService = service; | ||
57 | } | ||
58 | |||
59 | public override byte[] Handle(string path, Stream requestData, | ||
60 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||
61 | { | ||
62 | StreamReader sr = new StreamReader(requestData); | ||
63 | string body = sr.ReadToEnd(); | ||
64 | sr.Close(); | ||
65 | body = body.Trim(); | ||
66 | |||
67 | // We need to check the authorization header | ||
68 | //httpRequest.Headers["authorization"] ... | ||
69 | |||
70 | //m_log.DebugFormat("[XXX]: query String: {0}", body); | ||
71 | |||
72 | try | ||
73 | { | ||
74 | Dictionary<string, object> request = | ||
75 | ServerUtils.ParseQueryString(body); | ||
76 | |||
77 | if (!request.ContainsKey("METHOD")) | ||
78 | return FailureResult(); | ||
79 | |||
80 | string method = request["METHOD"].ToString(); | ||
81 | |||
82 | switch (method) | ||
83 | { | ||
84 | case "getaccount": | ||
85 | return GetAccount(request); | ||
86 | case "getaccounts": | ||
87 | return GetAccounts(request); | ||
88 | case "createaccount": | ||
89 | return CreateAccount(request); | ||
90 | case "setaccount": | ||
91 | return SetAccount(request); | ||
92 | } | ||
93 | m_log.DebugFormat("[PRESENCE HANDLER]: unknown method request: {0}", method); | ||
94 | } | ||
95 | catch (Exception e) | ||
96 | { | ||
97 | m_log.Debug("[PRESENCE HANDLER]: Exception {0}" + e); | ||
98 | } | ||
99 | |||
100 | return FailureResult(); | ||
101 | |||
102 | } | ||
103 | |||
104 | byte[] GetAccount(Dictionary<string, object> request) | ||
105 | { | ||
106 | UserAccount account = null; | ||
107 | UUID scopeID = UUID.Zero; | ||
108 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
109 | |||
110 | if (!request.ContainsKey("ScopeID")) | ||
111 | { | ||
112 | result["result"] = "null"; | ||
113 | return ResultToBytes(result); | ||
114 | } | ||
115 | |||
116 | if (!UUID.TryParse(request["ScopeID"].ToString(), out scopeID)) | ||
117 | { | ||
118 | result["result"] = "null"; | ||
119 | return ResultToBytes(result); | ||
120 | } | ||
121 | |||
122 | if (request.ContainsKey("UserID") && request["UserID"] != null) | ||
123 | { | ||
124 | UUID userID; | ||
125 | if (UUID.TryParse(request["UserID"].ToString(), out userID)) | ||
126 | account = m_UserAccountService.GetUserAccount(scopeID, userID); | ||
127 | } | ||
128 | |||
129 | else if (request.ContainsKey("Email") && request["Email"] != null) | ||
130 | account = m_UserAccountService.GetUserAccount(scopeID, request["Email"].ToString()); | ||
131 | |||
132 | else if (request.ContainsKey("FirstName") && request.ContainsKey("LastName") && | ||
133 | request["FirstName"] != null && request["LastName"] != null) | ||
134 | account = m_UserAccountService.GetUserAccount(scopeID, request["FirstName"].ToString(), request["LastName"].ToString()); | ||
135 | |||
136 | if (account == null) | ||
137 | result["result"] = "null"; | ||
138 | else | ||
139 | result["result"] = account.ToKeyValuePairs(); | ||
140 | |||
141 | return ResultToBytes(result); | ||
142 | } | ||
143 | |||
144 | byte[] GetAccounts(Dictionary<string, object> request) | ||
145 | { | ||
146 | if (!request.ContainsKey("ScopeID") || !request.ContainsKey("query")) | ||
147 | return FailureResult(); | ||
148 | |||
149 | UUID scopeID = UUID.Zero; | ||
150 | if (!UUID.TryParse(request["ScopeID"].ToString(), out scopeID)) | ||
151 | return FailureResult(); | ||
152 | |||
153 | string query = request["query"].ToString(); | ||
154 | |||
155 | List<UserAccount> accounts = m_UserAccountService.GetUserAccounts(scopeID, query); | ||
156 | |||
157 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
158 | if ((accounts == null) || ((accounts != null) && (accounts.Count == 0))) | ||
159 | result["result"] = "null"; | ||
160 | else | ||
161 | { | ||
162 | int i = 0; | ||
163 | foreach (UserAccount acc in accounts) | ||
164 | { | ||
165 | Dictionary<string, object> rinfoDict = acc.ToKeyValuePairs(); | ||
166 | result["account" + i] = rinfoDict; | ||
167 | i++; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
172 | //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); | ||
173 | UTF8Encoding encoding = new UTF8Encoding(); | ||
174 | return encoding.GetBytes(xmlString); | ||
175 | } | ||
176 | |||
177 | byte[] CreateAccount(Dictionary<string, object> request) | ||
178 | { | ||
179 | if (!request.ContainsKey("account")) | ||
180 | return FailureResult(); | ||
181 | if (request["account"] == null) | ||
182 | return FailureResult(); | ||
183 | if (!(request["account"] is Dictionary<string, object>)) | ||
184 | return FailureResult(); | ||
185 | |||
186 | UserAccount account = new UserAccount((Dictionary<string, object>) request["account"]); | ||
187 | |||
188 | if (m_UserAccountService.CreateUserAccount(account)) | ||
189 | return SuccessResult(); | ||
190 | |||
191 | return FailureResult(); | ||
192 | } | ||
193 | |||
194 | byte[] SetAccount(Dictionary<string, object> request) | ||
195 | { | ||
196 | if (!request.ContainsKey("account")) | ||
197 | return FailureResult(); | ||
198 | if (request["account"] == null) | ||
199 | return FailureResult(); | ||
200 | if (!(request["account"] is Dictionary<string, object>)) | ||
201 | return FailureResult(); | ||
202 | |||
203 | UserAccount account = new UserAccount((Dictionary<string, object>)request["account"]); | ||
204 | |||
205 | if (m_UserAccountService.SetUserAccount(account)) | ||
206 | return SuccessResult(); | ||
207 | |||
208 | return FailureResult(); | ||
209 | } | ||
210 | |||
211 | private byte[] SuccessResult() | ||
212 | { | ||
213 | XmlDocument doc = new XmlDocument(); | ||
214 | |||
215 | XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, | ||
216 | "", ""); | ||
217 | |||
218 | doc.AppendChild(xmlnode); | ||
219 | |||
220 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", | ||
221 | ""); | ||
222 | |||
223 | doc.AppendChild(rootElement); | ||
224 | |||
225 | XmlElement result = doc.CreateElement("", "result", ""); | ||
226 | result.AppendChild(doc.CreateTextNode("Success")); | ||
227 | |||
228 | rootElement.AppendChild(result); | ||
229 | |||
230 | return DocToBytes(doc); | ||
231 | } | ||
232 | |||
233 | private byte[] FailureResult() | ||
234 | { | ||
235 | XmlDocument doc = new XmlDocument(); | ||
236 | |||
237 | XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, | ||
238 | "", ""); | ||
239 | |||
240 | doc.AppendChild(xmlnode); | ||
241 | |||
242 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", | ||
243 | ""); | ||
244 | |||
245 | doc.AppendChild(rootElement); | ||
246 | |||
247 | XmlElement result = doc.CreateElement("", "result", ""); | ||
248 | result.AppendChild(doc.CreateTextNode("Failure")); | ||
249 | |||
250 | rootElement.AppendChild(result); | ||
251 | |||
252 | return DocToBytes(doc); | ||
253 | } | ||
254 | |||
255 | private byte[] DocToBytes(XmlDocument doc) | ||
256 | { | ||
257 | MemoryStream ms = new MemoryStream(); | ||
258 | XmlTextWriter xw = new XmlTextWriter(ms, null); | ||
259 | xw.Formatting = Formatting.Indented; | ||
260 | doc.WriteTo(xw); | ||
261 | xw.Flush(); | ||
262 | |||
263 | return ms.ToArray(); | ||
264 | } | ||
265 | |||
266 | private byte[] ResultToBytes(Dictionary<string, object> result) | ||
267 | { | ||
268 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
269 | //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); | ||
270 | UTF8Encoding encoding = new UTF8Encoding(); | ||
271 | return encoding.GetBytes(xmlString); | ||
272 | } | ||
273 | |||
274 | |||
275 | } | ||
276 | } | ||
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs index 50e817e..19bb3e2 100644 --- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs | |||
@@ -84,7 +84,7 @@ namespace OpenSim.Services.Connectors | |||
84 | 84 | ||
85 | public string Authenticate(UUID principalID, string password, int lifetime) | 85 | public string Authenticate(UUID principalID, string password, int lifetime) |
86 | { | 86 | { |
87 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 87 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
88 | sendData["LIFETIME"] = lifetime.ToString(); | 88 | sendData["LIFETIME"] = lifetime.ToString(); |
89 | sendData["PRINCIPAL"] = principalID.ToString(); | 89 | sendData["PRINCIPAL"] = principalID.ToString(); |
90 | sendData["PASSWORD"] = password; | 90 | sendData["PASSWORD"] = password; |
@@ -106,7 +106,7 @@ namespace OpenSim.Services.Connectors | |||
106 | 106 | ||
107 | public bool Verify(UUID principalID, string token, int lifetime) | 107 | public bool Verify(UUID principalID, string token, int lifetime) |
108 | { | 108 | { |
109 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 109 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
110 | sendData["LIFETIME"] = lifetime.ToString(); | 110 | sendData["LIFETIME"] = lifetime.ToString(); |
111 | sendData["PRINCIPAL"] = principalID.ToString(); | 111 | sendData["PRINCIPAL"] = principalID.ToString(); |
112 | sendData["TOKEN"] = token; | 112 | sendData["TOKEN"] = token; |
@@ -128,7 +128,7 @@ namespace OpenSim.Services.Connectors | |||
128 | 128 | ||
129 | public bool Release(UUID principalID, string token) | 129 | public bool Release(UUID principalID, string token) |
130 | { | 130 | { |
131 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 131 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
132 | sendData["PRINCIPAL"] = principalID.ToString(); | 132 | sendData["PRINCIPAL"] = principalID.ToString(); |
133 | sendData["TOKEN"] = token; | 133 | sendData["TOKEN"] = token; |
134 | 134 | ||
diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index 02f2b79..99aa3fb 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs | |||
@@ -89,7 +89,7 @@ namespace OpenSim.Services.Connectors | |||
89 | public virtual bool RegisterRegion(UUID scopeID, GridRegion regionInfo) | 89 | public virtual bool RegisterRegion(UUID scopeID, GridRegion regionInfo) |
90 | { | 90 | { |
91 | Dictionary<string, object> rinfo = regionInfo.ToKeyValuePairs(); | 91 | Dictionary<string, object> rinfo = regionInfo.ToKeyValuePairs(); |
92 | Dictionary<string, string> sendData = new Dictionary<string,string>(); | 92 | Dictionary<string, object> sendData = new Dictionary<string,object>(); |
93 | foreach (KeyValuePair<string, object> kvp in rinfo) | 93 | foreach (KeyValuePair<string, object> kvp in rinfo) |
94 | sendData[kvp.Key] = (string)kvp.Value; | 94 | sendData[kvp.Key] = (string)kvp.Value; |
95 | 95 | ||
@@ -130,7 +130,7 @@ namespace OpenSim.Services.Connectors | |||
130 | 130 | ||
131 | public virtual bool DeregisterRegion(UUID regionID) | 131 | public virtual bool DeregisterRegion(UUID regionID) |
132 | { | 132 | { |
133 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 133 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
134 | 134 | ||
135 | sendData["REGIONID"] = regionID.ToString(); | 135 | sendData["REGIONID"] = regionID.ToString(); |
136 | 136 | ||
@@ -162,7 +162,7 @@ namespace OpenSim.Services.Connectors | |||
162 | 162 | ||
163 | public virtual List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID) | 163 | public virtual List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID) |
164 | { | 164 | { |
165 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 165 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
166 | 166 | ||
167 | sendData["SCOPEID"] = scopeID.ToString(); | 167 | sendData["SCOPEID"] = scopeID.ToString(); |
168 | sendData["REGIONID"] = regionID.ToString(); | 168 | sendData["REGIONID"] = regionID.ToString(); |
@@ -212,7 +212,7 @@ namespace OpenSim.Services.Connectors | |||
212 | 212 | ||
213 | public virtual GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) | 213 | public virtual GridRegion GetRegionByUUID(UUID scopeID, UUID regionID) |
214 | { | 214 | { |
215 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 215 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
216 | 216 | ||
217 | sendData["SCOPEID"] = scopeID.ToString(); | 217 | sendData["SCOPEID"] = scopeID.ToString(); |
218 | sendData["REGIONID"] = regionID.ToString(); | 218 | sendData["REGIONID"] = regionID.ToString(); |
@@ -258,7 +258,7 @@ namespace OpenSim.Services.Connectors | |||
258 | 258 | ||
259 | public virtual GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 259 | public virtual GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
260 | { | 260 | { |
261 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 261 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
262 | 262 | ||
263 | sendData["SCOPEID"] = scopeID.ToString(); | 263 | sendData["SCOPEID"] = scopeID.ToString(); |
264 | sendData["X"] = x.ToString(); | 264 | sendData["X"] = x.ToString(); |
@@ -303,7 +303,7 @@ namespace OpenSim.Services.Connectors | |||
303 | 303 | ||
304 | public virtual GridRegion GetRegionByName(UUID scopeID, string regionName) | 304 | public virtual GridRegion GetRegionByName(UUID scopeID, string regionName) |
305 | { | 305 | { |
306 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 306 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
307 | 307 | ||
308 | sendData["SCOPEID"] = scopeID.ToString(); | 308 | sendData["SCOPEID"] = scopeID.ToString(); |
309 | sendData["NAME"] = regionName; | 309 | sendData["NAME"] = regionName; |
@@ -344,7 +344,7 @@ namespace OpenSim.Services.Connectors | |||
344 | 344 | ||
345 | public virtual List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) | 345 | public virtual List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) |
346 | { | 346 | { |
347 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 347 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
348 | 348 | ||
349 | sendData["SCOPEID"] = scopeID.ToString(); | 349 | sendData["SCOPEID"] = scopeID.ToString(); |
350 | sendData["NAME"] = name; | 350 | sendData["NAME"] = name; |
@@ -396,7 +396,7 @@ namespace OpenSim.Services.Connectors | |||
396 | 396 | ||
397 | public virtual List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) | 397 | public virtual List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) |
398 | { | 398 | { |
399 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | 399 | Dictionary<string, object> sendData = new Dictionary<string, object>(); |
400 | 400 | ||
401 | sendData["SCOPEID"] = scopeID.ToString(); | 401 | sendData["SCOPEID"] = scopeID.ToString(); |
402 | sendData["XMIN"] = xmin.ToString(); | 402 | sendData["XMIN"] = xmin.ToString(); |
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs new file mode 100644 index 0000000..29cfd6e --- /dev/null +++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using log4net; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Reflection; | ||
33 | using Nini.Config; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.Communications; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
39 | using OpenSim.Server.Base; | ||
40 | using OpenMetaverse; | ||
41 | |||
42 | namespace OpenSim.Services.Connectors | ||
43 | { | ||
44 | public class PresenceServicesConnector : IPresenceService | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private string m_ServerURI = String.Empty; | ||
51 | |||
52 | public PresenceServicesConnector() | ||
53 | { | ||
54 | } | ||
55 | |||
56 | public PresenceServicesConnector(string serverURI) | ||
57 | { | ||
58 | m_ServerURI = serverURI.TrimEnd('/'); | ||
59 | } | ||
60 | |||
61 | public PresenceServicesConnector(IConfigSource source) | ||
62 | { | ||
63 | Initialise(source); | ||
64 | } | ||
65 | |||
66 | public virtual void Initialise(IConfigSource source) | ||
67 | { | ||
68 | IConfig gridConfig = source.Configs["PresenceService"]; | ||
69 | if (gridConfig == null) | ||
70 | { | ||
71 | m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini"); | ||
72 | throw new Exception("Presence connector init error"); | ||
73 | } | ||
74 | |||
75 | string serviceURI = gridConfig.GetString("PresenceServerURI", | ||
76 | String.Empty); | ||
77 | |||
78 | if (serviceURI == String.Empty) | ||
79 | { | ||
80 | m_log.Error("[PRESENCE CONNECTOR]: No Server URI named in section PresenceService"); | ||
81 | throw new Exception("Presence connector init error"); | ||
82 | } | ||
83 | m_ServerURI = serviceURI; | ||
84 | } | ||
85 | |||
86 | |||
87 | #region IPresenceService | ||
88 | |||
89 | public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID) | ||
90 | { | ||
91 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
92 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
93 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
94 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
95 | sendData["METHOD"] = "login"; | ||
96 | |||
97 | sendData["UserID"] = userID; | ||
98 | sendData["SessionID"] = sessionID.ToString(); | ||
99 | sendData["SecureSessionID"] = secureSessionID.ToString(); | ||
100 | |||
101 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
102 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
103 | try | ||
104 | { | ||
105 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
106 | m_ServerURI + "/presence", | ||
107 | reqString); | ||
108 | if (reply != string.Empty) | ||
109 | { | ||
110 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
111 | |||
112 | if (replyData.ContainsKey("result")) | ||
113 | { | ||
114 | if (replyData["result"].ToString().ToLower() == "success") | ||
115 | return true; | ||
116 | else | ||
117 | return false; | ||
118 | } | ||
119 | else | ||
120 | m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent reply data does not contain result field"); | ||
121 | |||
122 | } | ||
123 | else | ||
124 | m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent received empty reply"); | ||
125 | } | ||
126 | catch (Exception e) | ||
127 | { | ||
128 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
129 | } | ||
130 | |||
131 | return false; | ||
132 | |||
133 | } | ||
134 | |||
135 | public bool LogoutAgent(UUID sessionID) | ||
136 | { | ||
137 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
138 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
139 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
140 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
141 | sendData["METHOD"] = "logout"; | ||
142 | |||
143 | sendData["SessionID"] = sessionID.ToString(); | ||
144 | |||
145 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
146 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
147 | try | ||
148 | { | ||
149 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
150 | m_ServerURI + "/presence", | ||
151 | reqString); | ||
152 | if (reply != string.Empty) | ||
153 | { | ||
154 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
155 | |||
156 | if (replyData.ContainsKey("result")) | ||
157 | { | ||
158 | if (replyData["result"].ToString().ToLower() == "success") | ||
159 | return true; | ||
160 | else | ||
161 | return false; | ||
162 | } | ||
163 | else | ||
164 | m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent reply data does not contain result field"); | ||
165 | |||
166 | } | ||
167 | else | ||
168 | m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent received empty reply"); | ||
169 | } | ||
170 | catch (Exception e) | ||
171 | { | ||
172 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
173 | } | ||
174 | |||
175 | return false; | ||
176 | } | ||
177 | |||
178 | public bool LogoutRegionAgents(UUID regionID) | ||
179 | { | ||
180 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
181 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
182 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
183 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
184 | sendData["METHOD"] = "logoutregion"; | ||
185 | |||
186 | sendData["RegionID"] = regionID.ToString(); | ||
187 | |||
188 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
189 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
190 | try | ||
191 | { | ||
192 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
193 | m_ServerURI + "/presence", | ||
194 | reqString); | ||
195 | if (reply != string.Empty) | ||
196 | { | ||
197 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
198 | |||
199 | if (replyData.ContainsKey("result")) | ||
200 | { | ||
201 | if (replyData["result"].ToString().ToLower() == "success") | ||
202 | return true; | ||
203 | else | ||
204 | return false; | ||
205 | } | ||
206 | else | ||
207 | m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents reply data does not contain result field"); | ||
208 | |||
209 | } | ||
210 | else | ||
211 | m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents received empty reply"); | ||
212 | } | ||
213 | catch (Exception e) | ||
214 | { | ||
215 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
216 | } | ||
217 | |||
218 | return false; | ||
219 | } | ||
220 | |||
221 | public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
222 | { | ||
223 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
224 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
225 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
226 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
227 | sendData["METHOD"] = "report"; | ||
228 | |||
229 | sendData["SessionID"] = sessionID.ToString(); | ||
230 | sendData["RegionID"] = regionID.ToString(); | ||
231 | sendData["position"] = position.ToString(); | ||
232 | sendData["lookAt"] = lookAt.ToString(); | ||
233 | |||
234 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
235 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
236 | try | ||
237 | { | ||
238 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
239 | m_ServerURI + "/presence", | ||
240 | reqString); | ||
241 | if (reply != string.Empty) | ||
242 | { | ||
243 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
244 | |||
245 | if (replyData.ContainsKey("result")) | ||
246 | { | ||
247 | if (replyData["result"].ToString().ToLower() == "success") | ||
248 | return true; | ||
249 | else | ||
250 | return false; | ||
251 | } | ||
252 | else | ||
253 | m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent reply data does not contain result field"); | ||
254 | |||
255 | } | ||
256 | else | ||
257 | m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent received empty reply"); | ||
258 | } | ||
259 | catch (Exception e) | ||
260 | { | ||
261 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
262 | } | ||
263 | |||
264 | return false; | ||
265 | } | ||
266 | |||
267 | public PresenceInfo GetAgent(UUID sessionID) | ||
268 | { | ||
269 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
270 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
271 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
272 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
273 | sendData["METHOD"] = "getagent"; | ||
274 | |||
275 | sendData["SessionID"] = sessionID.ToString(); | ||
276 | |||
277 | string reply = string.Empty; | ||
278 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
279 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
280 | try | ||
281 | { | ||
282 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
283 | m_ServerURI + "/presence", | ||
284 | reqString); | ||
285 | if (reply == null || (reply != null && reply == string.Empty)) | ||
286 | { | ||
287 | m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply"); | ||
288 | return null; | ||
289 | } | ||
290 | } | ||
291 | catch (Exception e) | ||
292 | { | ||
293 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
294 | } | ||
295 | |||
296 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
297 | PresenceInfo pinfo = null; | ||
298 | |||
299 | if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) | ||
300 | { | ||
301 | if (replyData["result"] is Dictionary<string, object>) | ||
302 | { | ||
303 | pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | return pinfo; | ||
308 | } | ||
309 | |||
310 | public PresenceInfo[] GetAgents(string[] userIDs) | ||
311 | { | ||
312 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
313 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
314 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
315 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
316 | sendData["METHOD"] = "getagents"; | ||
317 | |||
318 | sendData["uuids"] = new List<string>(userIDs); | ||
319 | |||
320 | string reply = string.Empty; | ||
321 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
322 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
323 | try | ||
324 | { | ||
325 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
326 | m_ServerURI + "/presence", | ||
327 | reqString); | ||
328 | if (reply == null || (reply != null && reply == string.Empty)) | ||
329 | { | ||
330 | m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply"); | ||
331 | return null; | ||
332 | } | ||
333 | } | ||
334 | catch (Exception e) | ||
335 | { | ||
336 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
337 | } | ||
338 | |||
339 | List<PresenceInfo> rinfos = new List<PresenceInfo>(); | ||
340 | |||
341 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
342 | |||
343 | if (replyData != null) | ||
344 | { | ||
345 | if (replyData.ContainsKey("result") && | ||
346 | (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure")) | ||
347 | { | ||
348 | return new PresenceInfo[0]; | ||
349 | } | ||
350 | |||
351 | Dictionary<string, object>.ValueCollection pinfosList = replyData.Values; | ||
352 | //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); | ||
353 | foreach (object presence in pinfosList) | ||
354 | { | ||
355 | if (presence is Dictionary<string, object>) | ||
356 | { | ||
357 | PresenceInfo pinfo = new PresenceInfo((Dictionary<string, object>)presence); | ||
358 | rinfos.Add(pinfo); | ||
359 | } | ||
360 | else | ||
361 | m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}", | ||
362 | presence.GetType()); | ||
363 | } | ||
364 | } | ||
365 | else | ||
366 | m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response"); | ||
367 | |||
368 | return rinfos.ToArray(); | ||
369 | } | ||
370 | |||
371 | |||
372 | public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
373 | { | ||
374 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
375 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
376 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
377 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
378 | sendData["METHOD"] = "sethome"; | ||
379 | |||
380 | sendData["UserID"] = userID; | ||
381 | sendData["RegionID"] = regionID.ToString(); | ||
382 | sendData["position"] = position.ToString(); | ||
383 | sendData["lookAt"] = lookAt.ToString(); | ||
384 | |||
385 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
386 | // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString); | ||
387 | try | ||
388 | { | ||
389 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
390 | m_ServerURI + "/presence", | ||
391 | reqString); | ||
392 | if (reply != string.Empty) | ||
393 | { | ||
394 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
395 | |||
396 | if (replyData.ContainsKey("result")) | ||
397 | { | ||
398 | if (replyData["result"].ToString().ToLower() == "success") | ||
399 | return true; | ||
400 | else | ||
401 | return false; | ||
402 | } | ||
403 | else | ||
404 | m_log.DebugFormat("[PRESENCE CONNECTOR]: SetHomeLocation reply data does not contain result field"); | ||
405 | |||
406 | } | ||
407 | else | ||
408 | m_log.DebugFormat("[PRESENCE CONNECTOR]: SetHomeLocation received empty reply"); | ||
409 | } | ||
410 | catch (Exception e) | ||
411 | { | ||
412 | m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message); | ||
413 | } | ||
414 | |||
415 | return false; | ||
416 | } | ||
417 | |||
418 | #endregion | ||
419 | |||
420 | } | ||
421 | } | ||
diff --git a/OpenSim/Services/Connectors/User/UserServiceConnector.cs b/OpenSim/Services/Connectors/User/UserServiceConnector.cs deleted file mode 100644 index 683990f..0000000 --- a/OpenSim/Services/Connectors/User/UserServiceConnector.cs +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using log4net; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Reflection; | ||
33 | using Nini.Config; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.Communications; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using OpenMetaverse; | ||
39 | |||
40 | namespace OpenSim.Services.Connectors | ||
41 | { | ||
42 | public class UserServicesConnector : IUserAccountService | ||
43 | { | ||
44 | private static readonly ILog m_log = | ||
45 | LogManager.GetLogger( | ||
46 | MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | // private string m_ServerURI = String.Empty; | ||
49 | |||
50 | public UserServicesConnector() | ||
51 | { | ||
52 | } | ||
53 | |||
54 | public UserServicesConnector(string serverURI) | ||
55 | { | ||
56 | // m_ServerURI = serverURI.TrimEnd('/'); | ||
57 | } | ||
58 | |||
59 | public UserServicesConnector(IConfigSource source) | ||
60 | { | ||
61 | Initialise(source); | ||
62 | } | ||
63 | |||
64 | public virtual void Initialise(IConfigSource source) | ||
65 | { | ||
66 | IConfig assetConfig = source.Configs["UserService"]; | ||
67 | if (assetConfig == null) | ||
68 | { | ||
69 | m_log.Error("[USER CONNECTOR]: UserService missing from OpanSim.ini"); | ||
70 | throw new Exception("User connector init error"); | ||
71 | } | ||
72 | |||
73 | string serviceURI = assetConfig.GetString("UserServerURI", | ||
74 | String.Empty); | ||
75 | |||
76 | if (serviceURI == String.Empty) | ||
77 | { | ||
78 | m_log.Error("[USER CONNECTOR]: No Server URI named in section UserService"); | ||
79 | throw new Exception("User connector init error"); | ||
80 | } | ||
81 | //m_ServerURI = serviceURI; | ||
82 | } | ||
83 | |||
84 | public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) | ||
85 | { | ||
86 | return null; | ||
87 | } | ||
88 | |||
89 | public UserAccount GetUserAccount(UUID scopeID, UUID userID) | ||
90 | { | ||
91 | return null; | ||
92 | } | ||
93 | |||
94 | public bool SetHomePosition(UserAccount data, UUID regionID, UUID regionSecret) | ||
95 | { | ||
96 | return false; | ||
97 | } | ||
98 | |||
99 | public bool SetUserAccount(UserAccount data, UUID principalID, string token) | ||
100 | { | ||
101 | return false; | ||
102 | } | ||
103 | |||
104 | public bool CreateUserAccount(UserAccount data, UUID principalID, string token) | ||
105 | { | ||
106 | return false; | ||
107 | } | ||
108 | |||
109 | public List<UserAccount> GetUserAccount(UUID scopeID, string query) | ||
110 | { | ||
111 | return null; | ||
112 | } | ||
113 | } | ||
114 | } | ||
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs new file mode 100644 index 0000000..d4b906a --- /dev/null +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs | |||
@@ -0,0 +1,287 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using log4net; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Reflection; | ||
33 | using Nini.Config; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.Communications; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Server.Base; | ||
38 | using OpenSim.Services.Interfaces; | ||
39 | using OpenMetaverse; | ||
40 | |||
41 | namespace OpenSim.Services.Connectors | ||
42 | { | ||
43 | public class UserAccountServicesConnector : IUserAccountService | ||
44 | { | ||
45 | private static readonly ILog m_log = | ||
46 | LogManager.GetLogger( | ||
47 | MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | private string m_ServerURI = String.Empty; | ||
50 | |||
51 | public UserAccountServicesConnector() | ||
52 | { | ||
53 | } | ||
54 | |||
55 | public UserAccountServicesConnector(string serverURI) | ||
56 | { | ||
57 | m_ServerURI = serverURI.TrimEnd('/'); | ||
58 | } | ||
59 | |||
60 | public UserAccountServicesConnector(IConfigSource source) | ||
61 | { | ||
62 | Initialise(source); | ||
63 | } | ||
64 | |||
65 | public virtual void Initialise(IConfigSource source) | ||
66 | { | ||
67 | IConfig assetConfig = source.Configs["UserAccountService"]; | ||
68 | if (assetConfig == null) | ||
69 | { | ||
70 | m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini"); | ||
71 | throw new Exception("User account connector init error"); | ||
72 | } | ||
73 | |||
74 | string serviceURI = assetConfig.GetString("UserAccountServerURI", | ||
75 | String.Empty); | ||
76 | |||
77 | if (serviceURI == String.Empty) | ||
78 | { | ||
79 | m_log.Error("[ACCOUNT CONNECTOR]: No Server URI named in section UserAccountService"); | ||
80 | throw new Exception("User account connector init error"); | ||
81 | } | ||
82 | m_ServerURI = serviceURI; | ||
83 | } | ||
84 | |||
85 | public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) | ||
86 | { | ||
87 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
88 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
89 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
90 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
91 | sendData["METHOD"] = "getaccount"; | ||
92 | |||
93 | sendData["ScopeID"] = scopeID; | ||
94 | sendData["FirstName"] = firstName.ToString(); | ||
95 | sendData["LastName"] = lastName.ToString(); | ||
96 | |||
97 | return SendAndGetReply(sendData); | ||
98 | } | ||
99 | |||
100 | public UserAccount GetUserAccount(UUID scopeID, string email) | ||
101 | { | ||
102 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
103 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
104 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
105 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
106 | sendData["METHOD"] = "getaccount"; | ||
107 | |||
108 | sendData["ScopeID"] = scopeID; | ||
109 | sendData["Email"] = email; | ||
110 | |||
111 | return SendAndGetReply(sendData); | ||
112 | } | ||
113 | |||
114 | public UserAccount GetUserAccount(UUID scopeID, UUID userID) | ||
115 | { | ||
116 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
117 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
118 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
119 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
120 | sendData["METHOD"] = "getaccount"; | ||
121 | |||
122 | sendData["ScopeID"] = scopeID; | ||
123 | sendData["UserID"] = userID.ToString(); | ||
124 | |||
125 | return SendAndGetReply(sendData); | ||
126 | } | ||
127 | |||
128 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) | ||
129 | { | ||
130 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
131 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
132 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
133 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
134 | sendData["METHOD"] = "getagents"; | ||
135 | |||
136 | sendData["ScopeID"] = scopeID.ToString(); | ||
137 | sendData["query"] = query; | ||
138 | |||
139 | string reply = string.Empty; | ||
140 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
141 | // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); | ||
142 | try | ||
143 | { | ||
144 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
145 | m_ServerURI + "/accounts", | ||
146 | reqString); | ||
147 | if (reply == null || (reply != null && reply == string.Empty)) | ||
148 | { | ||
149 | m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply"); | ||
150 | return null; | ||
151 | } | ||
152 | } | ||
153 | catch (Exception e) | ||
154 | { | ||
155 | m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting accounts server: {0}", e.Message); | ||
156 | } | ||
157 | |||
158 | List<UserAccount> accounts = new List<UserAccount>(); | ||
159 | |||
160 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
161 | |||
162 | if (replyData != null) | ||
163 | { | ||
164 | if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null") | ||
165 | { | ||
166 | return accounts; | ||
167 | } | ||
168 | |||
169 | Dictionary<string, object>.ValueCollection accountList = replyData.Values; | ||
170 | //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count); | ||
171 | foreach (object acc in accountList) | ||
172 | { | ||
173 | if (acc is Dictionary<string, object>) | ||
174 | { | ||
175 | UserAccount pinfo = new UserAccount((Dictionary<string, object>)acc); | ||
176 | accounts.Add(pinfo); | ||
177 | } | ||
178 | else | ||
179 | m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received invalid response type {0}", | ||
180 | acc.GetType()); | ||
181 | } | ||
182 | } | ||
183 | else | ||
184 | m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccounts received null response"); | ||
185 | |||
186 | return accounts; | ||
187 | } | ||
188 | |||
189 | public bool SetUserAccount(UserAccount data) | ||
190 | { | ||
191 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
192 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
193 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
194 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
195 | sendData["METHOD"] = "setaccount"; | ||
196 | |||
197 | sendData["account"] = data.ToKeyValuePairs(); | ||
198 | |||
199 | return SendAndGetBoolReply(sendData); | ||
200 | } | ||
201 | |||
202 | public bool CreateUserAccount(UserAccount data) | ||
203 | { | ||
204 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
205 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
206 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
207 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
208 | sendData["METHOD"] = "createaccount"; | ||
209 | |||
210 | sendData["account"] = data.ToKeyValuePairs(); | ||
211 | |||
212 | return SendAndGetBoolReply(sendData); | ||
213 | } | ||
214 | |||
215 | private UserAccount SendAndGetReply(Dictionary<string, object> sendData) | ||
216 | { | ||
217 | string reply = string.Empty; | ||
218 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
219 | // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); | ||
220 | try | ||
221 | { | ||
222 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
223 | m_ServerURI + "/accounts", | ||
224 | reqString); | ||
225 | if (reply == null || (reply != null && reply == string.Empty)) | ||
226 | { | ||
227 | m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply"); | ||
228 | return null; | ||
229 | } | ||
230 | } | ||
231 | catch (Exception e) | ||
232 | { | ||
233 | m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user account server: {0}", e.Message); | ||
234 | } | ||
235 | |||
236 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
237 | UserAccount account = null; | ||
238 | |||
239 | if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) | ||
240 | { | ||
241 | if (replyData["result"] is Dictionary<string, object>) | ||
242 | { | ||
243 | account = new UserAccount((Dictionary<string, object>)replyData["result"]); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | return account; | ||
248 | |||
249 | } | ||
250 | |||
251 | private bool SendAndGetBoolReply(Dictionary<string, object> sendData) | ||
252 | { | ||
253 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
254 | // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); | ||
255 | try | ||
256 | { | ||
257 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
258 | m_ServerURI + "/accounts", | ||
259 | reqString); | ||
260 | if (reply != string.Empty) | ||
261 | { | ||
262 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
263 | |||
264 | if (replyData.ContainsKey("result")) | ||
265 | { | ||
266 | if (replyData["result"].ToString().ToLower() == "success") | ||
267 | return true; | ||
268 | else | ||
269 | return false; | ||
270 | } | ||
271 | else | ||
272 | m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount reply data does not contain result field"); | ||
273 | |||
274 | } | ||
275 | else | ||
276 | m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount received empty reply"); | ||
277 | } | ||
278 | catch (Exception e) | ||
279 | { | ||
280 | m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Exception when contacting user account server: {0}", e.Message); | ||
281 | } | ||
282 | |||
283 | return false; | ||
284 | } | ||
285 | |||
286 | } | ||
287 | } | ||
diff --git a/OpenSim/Services/Interfaces/IPresenceService.cs b/OpenSim/Services/Interfaces/IPresenceService.cs index aa1c5bf..2dad7e6 100644 --- a/OpenSim/Services/Interfaces/IPresenceService.cs +++ b/OpenSim/Services/Interfaces/IPresenceService.cs | |||
@@ -25,6 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | ||
28 | using OpenSim.Framework; | 29 | using OpenSim.Framework; |
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using OpenMetaverse; | 31 | using OpenMetaverse; |
@@ -33,13 +34,74 @@ namespace OpenSim.Services.Interfaces | |||
33 | { | 34 | { |
34 | public class PresenceInfo | 35 | public class PresenceInfo |
35 | { | 36 | { |
36 | public UUID PrincipalID; | 37 | public string UserID; |
37 | public UUID RegionID; | 38 | public UUID RegionID; |
38 | public Dictionary<string, string> Data; | 39 | public bool Online; |
40 | public DateTime Login; | ||
41 | public DateTime Logout; | ||
42 | public Vector3 Position; | ||
43 | public Vector3 LookAt; | ||
44 | public UUID HomeRegionID; | ||
45 | public Vector3 HomePosition; | ||
46 | public Vector3 HomeLookAt; | ||
47 | |||
48 | public PresenceInfo() | ||
49 | { | ||
50 | } | ||
51 | |||
52 | public PresenceInfo(Dictionary<string, object> kvp) | ||
53 | { | ||
54 | if (kvp.ContainsKey("UserID")) | ||
55 | UserID = kvp["UserID"].ToString(); | ||
56 | if (kvp.ContainsKey("RegionID")) | ||
57 | UUID.TryParse(kvp["RegionID"].ToString(), out RegionID); | ||
58 | if (kvp.ContainsKey("login")) | ||
59 | DateTime.TryParse(kvp["login"].ToString(), out Login); | ||
60 | if (kvp.ContainsKey("logout")) | ||
61 | DateTime.TryParse(kvp["logout"].ToString(), out Logout); | ||
62 | if (kvp.ContainsKey("lookAt")) | ||
63 | Vector3.TryParse(kvp["lookAt"].ToString(), out LookAt); | ||
64 | if (kvp.ContainsKey("online")) | ||
65 | Boolean.TryParse(kvp["online"].ToString(), out Online); | ||
66 | if (kvp.ContainsKey("position")) | ||
67 | Vector3.TryParse(kvp["position"].ToString(), out Position); | ||
68 | if (kvp.ContainsKey("HomeRegionID")) | ||
69 | UUID.TryParse(kvp["HomeRegionID"].ToString(), out HomeRegionID); | ||
70 | if (kvp.ContainsKey("HomePosition")) | ||
71 | Vector3.TryParse(kvp["HomePosition"].ToString(), out HomePosition); | ||
72 | if (kvp.ContainsKey("HomeLookAt")) | ||
73 | Vector3.TryParse(kvp["HomeLookAt"].ToString(), out HomeLookAt); | ||
74 | |||
75 | } | ||
76 | |||
77 | public Dictionary<string, object> ToKeyValuePairs() | ||
78 | { | ||
79 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
80 | result["UserID"] = UserID; | ||
81 | result["RegionID"] = RegionID.ToString(); | ||
82 | result["online"] = Online.ToString(); | ||
83 | result["login"] = Login.ToString(); | ||
84 | result["logout"] = Logout.ToString(); | ||
85 | result["position"] = Position.ToString(); | ||
86 | result["lookAt"] = LookAt.ToString(); | ||
87 | result["HomeRegionID"] = HomeRegionID.ToString(); | ||
88 | result["HomePosition"] = HomePosition.ToString(); | ||
89 | result["HomeLookAt"] = HomeLookAt.ToString(); | ||
90 | |||
91 | return result; | ||
92 | } | ||
39 | } | 93 | } |
40 | 94 | ||
41 | public interface IPresenceService | 95 | public interface IPresenceService |
42 | { | 96 | { |
43 | bool Report(PresenceInfo presence); | 97 | bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID); |
98 | bool LogoutAgent(UUID sessionID); | ||
99 | bool LogoutRegionAgents(UUID regionID); | ||
100 | |||
101 | bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt); | ||
102 | bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt); | ||
103 | |||
104 | PresenceInfo GetAgent(UUID sessionID); | ||
105 | PresenceInfo[] GetAgents(string[] userIDs); | ||
44 | } | 106 | } |
45 | } | 107 | } |
diff --git a/OpenSim/Services/Interfaces/IUserService.cs b/OpenSim/Services/Interfaces/IUserService.cs index 92bd8ef..1bdaaab 100644 --- a/OpenSim/Services/Interfaces/IUserService.cs +++ b/OpenSim/Services/Interfaces/IUserService.cs | |||
@@ -25,6 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | ||
28 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | 31 | ||
@@ -36,68 +37,69 @@ namespace OpenSim.Services.Interfaces | |||
36 | { | 37 | { |
37 | } | 38 | } |
38 | 39 | ||
39 | public UserAccount(UUID userID, UUID homeRegionID, float homePositionX, | 40 | public UserAccount(UUID principalID) |
40 | float homePositionY, float homePositionZ, float homeLookAtX, | ||
41 | float homeLookAtY, float homeLookAtZ) | ||
42 | { | 41 | { |
43 | UserID = userID; | 42 | PrincipalID = principalID; |
44 | HomeRegionID = homeRegionID; | ||
45 | HomePositionX = homePositionX; | ||
46 | HomePositionY = homePositionY; | ||
47 | HomePositionZ = homePositionZ; | ||
48 | HomeLookAtX = homeLookAtX; | ||
49 | HomeLookAtY = homeLookAtY; | ||
50 | HomeLookAtZ = homeLookAtZ; | ||
51 | } | 43 | } |
52 | 44 | ||
53 | public string FirstName; | 45 | public string FirstName; |
54 | public string LastName; | 46 | public string LastName; |
55 | public UUID UserID; | 47 | public string Email; |
48 | public UUID PrincipalID; | ||
56 | public UUID ScopeID; | 49 | public UUID ScopeID; |
57 | 50 | ||
58 | // For informational purposes only! | 51 | public Dictionary<string, object> ServiceURLs; |
59 | // | ||
60 | public string HomeRegionName; | ||
61 | 52 | ||
62 | public UUID HomeRegionID; | 53 | public int Created; |
63 | public float HomePositionX; | ||
64 | public float HomePositionY; | ||
65 | public float HomePositionZ; | ||
66 | public float HomeLookAtX; | ||
67 | public float HomeLookAtY; | ||
68 | public float HomeLookAtZ; | ||
69 | 54 | ||
70 | // These are here because they | 55 | public UserAccount(Dictionary<string, object> kvp) |
71 | // concern the account rather than | 56 | { |
72 | // the profile. They just happen to | 57 | if (kvp.ContainsKey("FirstName")) |
73 | // be used in the Linden profile as well | 58 | FirstName = kvp["FirstName"].ToString(); |
74 | // | 59 | if (kvp.ContainsKey("LastName")) |
75 | public int GodLevel; | 60 | LastName = kvp["LastName"].ToString(); |
76 | public int UserFlags; | 61 | if (kvp.ContainsKey("Email")) |
77 | public string AccountType; | 62 | Email = kvp["Email"].ToString(); |
63 | if (kvp.ContainsKey("PrincipalID")) | ||
64 | UUID.TryParse(kvp["PrincipalID"].ToString(), out PrincipalID); | ||
65 | if (kvp.ContainsKey("ScopeID")) | ||
66 | UUID.TryParse(kvp["ScopeID"].ToString(), out ScopeID); | ||
67 | if (kvp.ContainsKey("Created")) | ||
68 | Convert.ToInt32(kvp["Created"].ToString()); | ||
69 | if (kvp.ContainsKey("ServiceURLs") && kvp["ServiceURLs"] != null && (kvp["ServiceURLs"] is Dictionary<string, string>)) | ||
70 | ServiceURLs = (Dictionary<string, object>)kvp["ServiceURLs"]; | ||
71 | } | ||
72 | |||
73 | public Dictionary<string, object> ToKeyValuePairs() | ||
74 | { | ||
75 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
76 | result["FirstName"] = FirstName; | ||
77 | result["LastName"] = LastName; | ||
78 | result["Email"] = Email; | ||
79 | result["PrincipalID"] = PrincipalID.ToString(); | ||
80 | result["ScopeID"] = ScopeID.ToString(); | ||
81 | result["Created"] = Created.ToString(); | ||
82 | result["ServiceURLs"] = ServiceURLs; | ||
78 | 83 | ||
84 | return result; | ||
85 | } | ||
79 | }; | 86 | }; |
80 | 87 | ||
81 | public interface IUserAccountService | 88 | public interface IUserAccountService |
82 | { | 89 | { |
83 | UserAccount GetUserAccount(UUID scopeID, UUID userID); | 90 | UserAccount GetUserAccount(UUID scopeID, UUID userID); |
84 | UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName); | 91 | UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName); |
92 | UserAccount GetUserAccount(UUID scopeID, string Email); | ||
85 | // Returns the list of avatars that matches both the search | 93 | // Returns the list of avatars that matches both the search |
86 | // criterion and the scope ID passed | 94 | // criterion and the scope ID passed |
87 | // | 95 | // |
88 | List<UserAccount> GetUserAccount(UUID scopeID, string query); | 96 | List<UserAccount> GetUserAccounts(UUID scopeID, string query); |
89 | |||
90 | |||
91 | // This will set only the home region portion of the data! | ||
92 | // Can't be used to set god level, flags, type or change the name! | ||
93 | // | ||
94 | bool SetHomePosition(UserAccount data, UUID RegionID, UUID RegionSecret); | ||
95 | 97 | ||
96 | // Update all updatable fields | 98 | // Update all updatable fields |
97 | // | 99 | // |
98 | bool SetUserAccount(UserAccount data, UUID PrincipalID, string token); | 100 | bool SetUserAccount(UserAccount data); |
99 | 101 | ||
100 | // Creates a user data record | 102 | // Creates a user data record |
101 | bool CreateUserAccount(UserAccount data, UUID PrincipalID, string token); | 103 | bool CreateUserAccount(UserAccount data); |
102 | } | 104 | } |
103 | } | 105 | } |
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs index 2157462..fc6a6e1 100644 --- a/OpenSim/Services/PresenceService/PresenceService.cs +++ b/OpenSim/Services/PresenceService/PresenceService.cs | |||
@@ -41,27 +41,151 @@ namespace OpenSim.Services.PresenceService | |||
41 | { | 41 | { |
42 | public class PresenceService : PresenceServiceBase, IPresenceService | 42 | public class PresenceService : PresenceServiceBase, IPresenceService |
43 | { | 43 | { |
44 | // private static readonly ILog m_log = | 44 | private static readonly ILog m_log = |
45 | // LogManager.GetLogger( | 45 | LogManager.GetLogger( |
46 | // MethodBase.GetCurrentMethod().DeclaringType); | 46 | MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | public PresenceService(IConfigSource config) | 48 | public PresenceService(IConfigSource config) |
49 | : base(config) | 49 | : base(config) |
50 | { | 50 | { |
51 | m_log.Debug("[PRESENCE SERVICE]: Starting presence service"); | ||
51 | } | 52 | } |
52 | 53 | ||
53 | public bool Report(PresenceInfo presence) | 54 | public bool LoginAgent(string userID, UUID sessionID, |
55 | UUID secureSessionID) | ||
54 | { | 56 | { |
55 | PresenceData p = new PresenceData(); | 57 | m_Database.Prune(userID); |
56 | p.Data = new Dictionary<string, string>(); | ||
57 | 58 | ||
58 | p.UUID = presence.PrincipalID; | 59 | PresenceData[] d = m_Database.Get("UserID", userID); |
59 | p.currentRegion = presence.RegionID; | ||
60 | 60 | ||
61 | foreach (KeyValuePair<string, string> kvp in presence.Data) | 61 | PresenceData data = new PresenceData(); |
62 | p.Data[kvp.Key] = kvp.Value; | ||
63 | 62 | ||
64 | return false; | 63 | data.UserID = userID; |
64 | data.RegionID = UUID.Zero; | ||
65 | data.SessionID = sessionID; | ||
66 | data.Data["SecureSessionID"] = secureSessionID.ToString(); | ||
67 | data.Data["Online"] = "true"; | ||
68 | data.Data["Login"] = Util.UnixTimeSinceEpoch().ToString(); | ||
69 | if (d.Length > 0) | ||
70 | { | ||
71 | data.Data["HomeRegionID"] = d[0].Data["HomeRegionID"]; | ||
72 | data.Data["HomePosition"] = d[0].Data["HomePosition"]; | ||
73 | data.Data["HomeLookAt"] = d[0].Data["HomeLookAt"]; | ||
74 | } | ||
75 | |||
76 | m_Database.Store(data); | ||
77 | |||
78 | return true; | ||
79 | } | ||
80 | |||
81 | public bool LogoutAgent(UUID sessionID) | ||
82 | { | ||
83 | PresenceData data = m_Database.Get(sessionID); | ||
84 | if (data == null) | ||
85 | return false; | ||
86 | |||
87 | PresenceData[] d = m_Database.Get("UserID", data.UserID); | ||
88 | |||
89 | if (d.Length > 1) | ||
90 | { | ||
91 | m_Database.Delete("SessionID", sessionID.ToString()); | ||
92 | } | ||
93 | |||
94 | data.Data["Online"] = "false"; | ||
95 | data.Data["Logout"] = Util.UnixTimeSinceEpoch().ToString(); | ||
96 | |||
97 | m_Database.Store(data); | ||
98 | |||
99 | return true; | ||
100 | } | ||
101 | |||
102 | public bool LogoutRegionAgents(UUID regionID) | ||
103 | { | ||
104 | m_Database.LogoutRegionAgents(regionID); | ||
105 | |||
106 | return true; | ||
107 | } | ||
108 | |||
109 | |||
110 | public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
111 | { | ||
112 | m_log.DebugFormat("[PRESENCE SERVICE]: ReportAgent with session {0} in region {1}", sessionID, regionID); | ||
113 | PresenceData pdata = m_Database.Get(sessionID); | ||
114 | if (pdata == null) | ||
115 | return false; | ||
116 | if (pdata.Data["Online"] == "false") | ||
117 | return false; | ||
118 | |||
119 | return m_Database.ReportAgent(sessionID, regionID, | ||
120 | position.ToString(), lookAt.ToString()); | ||
121 | } | ||
122 | |||
123 | public PresenceInfo GetAgent(UUID sessionID) | ||
124 | { | ||
125 | PresenceInfo ret = new PresenceInfo(); | ||
126 | |||
127 | PresenceData data = m_Database.Get(sessionID); | ||
128 | if (data == null) | ||
129 | return null; | ||
130 | |||
131 | ret.UserID = data.UserID; | ||
132 | ret.RegionID = data.RegionID; | ||
133 | if (data.Data.ContainsKey("Online")) | ||
134 | ret.Online = bool.Parse(data.Data["Online"]); | ||
135 | if (data.Data.ContainsKey("Login")) | ||
136 | ret.Login = Util.ToDateTime(Convert.ToInt32(data.Data["Login"])); | ||
137 | if (data.Data.ContainsKey("Logout")) | ||
138 | ret.Logout = Util.ToDateTime(Convert.ToInt32(data.Data["Logout"])); | ||
139 | if (data.Data.ContainsKey("Position")) | ||
140 | ret.Position = Vector3.Parse(data.Data["Position"]); | ||
141 | if (data.Data.ContainsKey("LookAt")) | ||
142 | ret.LookAt = Vector3.Parse(data.Data["LookAt"]); | ||
143 | if (data.Data.ContainsKey("HomeRegionID")) | ||
144 | ret.HomeRegionID = new UUID(data.Data["HomeRegionID"]); | ||
145 | if (data.Data.ContainsKey("HomePosition")) | ||
146 | ret.HomePosition = Vector3.Parse(data.Data["HomePosition"]); | ||
147 | if (data.Data.ContainsKey("HomeLookAt")) | ||
148 | ret.HomeLookAt = Vector3.Parse(data.Data["HomeLookAt"]); | ||
149 | |||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | public PresenceInfo[] GetAgents(string[] userIDs) | ||
154 | { | ||
155 | List<PresenceInfo> info = new List<PresenceInfo>(); | ||
156 | |||
157 | foreach (string userIDStr in userIDs) | ||
158 | { | ||
159 | PresenceData[] data = m_Database.Get("UserID", | ||
160 | userIDStr); | ||
161 | |||
162 | foreach (PresenceData d in data) | ||
163 | { | ||
164 | PresenceInfo ret = new PresenceInfo(); | ||
165 | |||
166 | ret.UserID = d.UserID; | ||
167 | ret.RegionID = d.RegionID; | ||
168 | ret.Online = bool.Parse(d.Data["Online"]); | ||
169 | ret.Login = Util.ToDateTime(Convert.ToInt32( | ||
170 | d.Data["Login"])); | ||
171 | ret.Logout = Util.ToDateTime(Convert.ToInt32( | ||
172 | d.Data["Logout"])); | ||
173 | ret.Position = Vector3.Parse(d.Data["Position"]); | ||
174 | ret.LookAt = Vector3.Parse(d.Data["LookAt"]); | ||
175 | ret.HomeRegionID = new UUID(d.Data["HomeRegionID"]); | ||
176 | ret.HomePosition = Vector3.Parse(d.Data["HomePosition"]); | ||
177 | ret.HomeLookAt = Vector3.Parse(d.Data["HomeLookAt"]); | ||
178 | |||
179 | info.Add(ret); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | return info.ToArray(); | ||
184 | } | ||
185 | |||
186 | public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | ||
187 | { | ||
188 | return m_Database.SetHomeLocation(userID, regionID, position, lookAt); | ||
65 | } | 189 | } |
66 | } | 190 | } |
67 | } | 191 | } |
diff --git a/OpenSim/Services/PresenceService/PresenceServiceBase.cs b/OpenSim/Services/PresenceService/PresenceServiceBase.cs index 60a246b..3ca70c1 100644 --- a/OpenSim/Services/PresenceService/PresenceServiceBase.cs +++ b/OpenSim/Services/PresenceService/PresenceServiceBase.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Services.PresenceService | |||
44 | { | 44 | { |
45 | string dllName = String.Empty; | 45 | string dllName = String.Empty; |
46 | string connString = String.Empty; | 46 | string connString = String.Empty; |
47 | string realm = "agents"; | 47 | string realm = "presence"; |
48 | 48 | ||
49 | // | 49 | // |
50 | // Try reading the [DatabaseService] section, if it exists | 50 | // Try reading the [DatabaseService] section, if it exists |
diff --git a/OpenSim/Services/UserService/UserService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index e8b9fc3..ee9ea94 100644 --- a/OpenSim/Services/UserService/UserService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs | |||
@@ -44,31 +44,45 @@ namespace OpenSim.Services.UserAccountService | |||
44 | public UserAccount GetUserAccount(UUID scopeID, string firstName, | 44 | public UserAccount GetUserAccount(UUID scopeID, string firstName, |
45 | string lastName) | 45 | string lastName) |
46 | { | 46 | { |
47 | UserAccountData[] d = m_Database.Get( | ||
48 | new string[] {"ScopeID", "FirstName", "LastName"}, | ||
49 | new string[] {scopeID.ToString(), firstName, lastName}); | ||
50 | |||
51 | if (d.Length < 1) | ||
52 | return null; | ||
53 | |||
54 | UserAccount u = new UserAccount(); | ||
55 | u.FirstName = d[0].FirstName; | ||
56 | u.LastName = d[0].LastName; | ||
57 | u.PrincipalID = d[0].PrincipalID; | ||
58 | u.ScopeID = d[0].ScopeID; | ||
59 | u.Email = d[0].Data["Email"].ToString(); | ||
60 | u.Created = Convert.ToInt32(d[0].Data["Created"].ToString()); | ||
61 | |||
47 | return null; | 62 | return null; |
48 | } | 63 | } |
49 | 64 | ||
50 | public UserAccount GetUserAccount(UUID scopeID, UUID userID) | 65 | public UserAccount GetUserAccount(UUID scopeID, string email) |
51 | { | 66 | { |
52 | return null; | 67 | return null; |
53 | } | 68 | } |
54 | 69 | ||
55 | public bool SetHomePosition(UserAccount data, UUID regionID, UUID regionSecret) | 70 | public UserAccount GetUserAccount(UUID scopeID, UUID userID) |
56 | { | 71 | { |
57 | return false; | 72 | return null; |
58 | } | 73 | } |
59 | 74 | ||
60 | public bool SetUserAccount(UserAccount data, UUID principalID, string token) | 75 | public bool SetUserAccount(UserAccount data) |
61 | { | 76 | { |
62 | return false; | 77 | return false; |
63 | } | 78 | } |
64 | 79 | ||
65 | public bool CreateUserAccount(UserAccount data, UUID principalID, string token) | 80 | public bool CreateUserAccount(UserAccount data) |
66 | { | 81 | { |
67 | return false; | 82 | return false; |
68 | } | 83 | } |
69 | 84 | ||
70 | public List<UserAccount> GetUserAccount(UUID scopeID, | 85 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) |
71 | string query) | ||
72 | { | 86 | { |
73 | return null; | 87 | return null; |
74 | } | 88 | } |
diff --git a/OpenSim/Services/UserService/UserServiceBase.cs b/OpenSim/Services/UserAccountService/UserAccountServiceBase.cs index fea8b01..70ed594 100644 --- a/OpenSim/Services/UserService/UserServiceBase.cs +++ b/OpenSim/Services/UserAccountService/UserAccountServiceBase.cs | |||
@@ -40,20 +40,29 @@ namespace OpenSim.Services.UserAccountService | |||
40 | 40 | ||
41 | public UserAccountServiceBase(IConfigSource config) : base(config) | 41 | public UserAccountServiceBase(IConfigSource config) : base(config) |
42 | { | 42 | { |
43 | string dllName = String.Empty; | ||
44 | string connString = String.Empty; | ||
45 | string realm = "useraccounts"; | ||
46 | |||
47 | IConfig dbConfig = config.Configs["DatabaseService"]; | ||
48 | if (dbConfig != null) | ||
49 | { | ||
50 | dllName = dbConfig.GetString("StorageProvider", String.Empty); | ||
51 | connString = dbConfig.GetString("ConnectionString", String.Empty); | ||
52 | } | ||
53 | |||
43 | IConfig userConfig = config.Configs["UserAccountService"]; | 54 | IConfig userConfig = config.Configs["UserAccountService"]; |
44 | if (userConfig == null) | 55 | if (userConfig == null) |
45 | throw new Exception("No UserAccountService configuration"); | 56 | throw new Exception("No UserAccountService configuration"); |
46 | 57 | ||
47 | string dllName = userConfig.GetString("StorageProvider", | 58 | dllName = userConfig.GetString("StorageProvider", dllName); |
48 | String.Empty); | ||
49 | 59 | ||
50 | if (dllName == String.Empty) | 60 | if (dllName == String.Empty) |
51 | throw new Exception("No StorageProvider configured"); | 61 | throw new Exception("No StorageProvider configured"); |
52 | 62 | ||
53 | string connString = userConfig.GetString("ConnectionString", | 63 | connString = userConfig.GetString("ConnectionString", connString); |
54 | String.Empty); | ||
55 | 64 | ||
56 | string realm = userConfig.GetString("Realm", "users"); | 65 | realm = userConfig.GetString("Realm", realm); |
57 | 66 | ||
58 | m_Database = LoadPlugin<IUserAccountData>(dllName, new Object[] {connString, realm}); | 67 | m_Database = LoadPlugin<IUserAccountData>(dllName, new Object[] {connString, realm}); |
59 | 68 | ||
diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index cdfdf4b..e881e30 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini | |||
@@ -13,6 +13,8 @@ | |||
13 | NeighbourServices = "LocalNeighbourServicesConnector" | 13 | NeighbourServices = "LocalNeighbourServicesConnector" |
14 | AuthorizationServices = "LocalAuthorizationServicesConnector" | 14 | AuthorizationServices = "LocalAuthorizationServicesConnector" |
15 | GridServices = "LocalGridServicesConnector" | 15 | GridServices = "LocalGridServicesConnector" |
16 | PresenceServices = "LocalPresenceServicesConnector" | ||
17 | UserAccountServices = "LocalUserAccountServicesConnector" | ||
16 | LibraryModule = true | 18 | LibraryModule = true |
17 | 19 | ||
18 | [AssetService] | 20 | [AssetService] |
@@ -28,3 +30,8 @@ | |||
28 | LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" | 30 | LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" |
29 | Realm = "regions" | 31 | Realm = "regions" |
30 | 32 | ||
33 | [PresenceService] | ||
34 | LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" | ||
35 | |||
36 | [UserAccountService] | ||
37 | LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" | ||
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 909286c..c3ed754 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini | |||
@@ -16,6 +16,8 @@ | |||
16 | NeighbourServices = "RemoteNeighbourServicesConnector" | 16 | NeighbourServices = "RemoteNeighbourServicesConnector" |
17 | AuthorizationServices = "LocalAuthorizationServicesConnector" | 17 | AuthorizationServices = "LocalAuthorizationServicesConnector" |
18 | GridServices = "HGGridServicesConnector" | 18 | GridServices = "HGGridServicesConnector" |
19 | PresenceServices = "LocalPresenceServicesConnector" | ||
20 | UserAccountServices = "LocalUserAccountServicesConnector" | ||
19 | InventoryServiceInConnector = true | 21 | InventoryServiceInConnector = true |
20 | AssetServiceInConnector = true | 22 | AssetServiceInConnector = true |
21 | HGAuthServiceInConnector = true | 23 | HGAuthServiceInConnector = true |
@@ -52,3 +54,9 @@ | |||
52 | ; LocalGridServicesConnector needs this | 54 | ; LocalGridServicesConnector needs this |
53 | LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" | 55 | LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" |
54 | Realm = "regions" | 56 | Realm = "regions" |
57 | |||
58 | [PresenceService] | ||
59 | LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" | ||
60 | |||
61 | [UserAccountService] | ||
62 | LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" | ||
diff --git a/prebuild.xml b/prebuild.xml index 7881cd7..7e7ce28 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -1038,7 +1038,7 @@ | |||
1038 | </Files> | 1038 | </Files> |
1039 | </Project> | 1039 | </Project> |
1040 | 1040 | ||
1041 | <Project frameworkVersion="v3_5" name="OpenSim.Services.UserService" path="OpenSim/Services/UserService" type="Library"> | 1041 | <Project frameworkVersion="v3_5" name="OpenSim.Services.UserAccountService" path="OpenSim/Services/UserAccountService" type="Library"> |
1042 | <Configuration name="Debug"> | 1042 | <Configuration name="Debug"> |
1043 | <Options> | 1043 | <Options> |
1044 | <OutputPath>../../../bin/</OutputPath> | 1044 | <OutputPath>../../../bin/</OutputPath> |
@@ -3274,6 +3274,7 @@ | |||
3274 | <Match path="World/Serialiser/Tests" pattern="*.cs" recurse="true" /> | 3274 | <Match path="World/Serialiser/Tests" pattern="*.cs" recurse="true" /> |
3275 | <Match path="World/Terrain/Tests" pattern="*.cs" recurse="true" /> | 3275 | <Match path="World/Terrain/Tests" pattern="*.cs" recurse="true" /> |
3276 | <Match path="ServiceConnectorsOut/Grid/Tests" pattern="*.cs" recurse="true" /> | 3276 | <Match path="ServiceConnectorsOut/Grid/Tests" pattern="*.cs" recurse="true" /> |
3277 | <Match path="ServiceConnectorsOut/Presence/Tests" pattern="*.cs" recurse="true" /> | ||
3277 | </Files> | 3278 | </Files> |
3278 | </Project> | 3279 | </Project> |
3279 | 3280 | ||