aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services')
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs22
-rw-r--r--OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs34
-rw-r--r--OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs32
-rw-r--r--OpenSim/Services/AvatarService/AvatarService.cs144
-rw-r--r--OpenSim/Services/AvatarService/AvatarServiceBase.cs84
-rw-r--r--OpenSim/Services/Base/ServiceBase.cs21
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs4
-rw-r--r--OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs10
-rw-r--r--OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs317
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs241
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs167
-rw-r--r--OpenSim/Services/Connectors/Grid/GridServiceConnector.cs152
-rw-r--r--OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs254
-rw-r--r--OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs230
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs272
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs402
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs216
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs381
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs438
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs246
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs262
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs240
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs47
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs421
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs907
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs575
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs435
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs311
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs613
-rw-r--r--OpenSim/Services/Connectors/User/UserServiceConnector.cs114
-rw-r--r--OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs278
-rw-r--r--OpenSim/Services/Friends/FriendsService.cs85
-rw-r--r--OpenSim/Services/Friends/FriendsServiceBase.cs89
-rw-r--r--OpenSim/Services/GridService/GridService.cs287
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs641
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs322
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs250
-rw-r--r--OpenSim/Services/Interfaces/IAttachmentsService.cs17
-rw-r--r--OpenSim/Services/Interfaces/IAuthenticationService.cs11
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs241
-rw-r--r--OpenSim/Services/Interfaces/IFriendsService.cs80
-rw-r--r--OpenSim/Services/Interfaces/IGatekeeperService.cs (renamed from OpenSim/Services/UserService/UserService.cs)62
-rw-r--r--OpenSim/Services/Interfaces/IGridService.cs24
-rw-r--r--OpenSim/Services/Interfaces/IGridUserService.cs115
-rw-r--r--OpenSim/Services/Interfaces/ILibraryService.cs (renamed from OpenSim/Services/Interfaces/IHyperlink.cs)22
-rw-r--r--OpenSim/Services/Interfaces/ILoginService.cs55
-rw-r--r--OpenSim/Services/Interfaces/IPresenceService.cs34
-rw-r--r--OpenSim/Services/Interfaces/ISimulationService.cs35
-rw-r--r--OpenSim/Services/Interfaces/IUserAccountService.cs159
-rw-r--r--OpenSim/Services/Interfaces/IUserService.cs103
-rw-r--r--OpenSim/Services/InventoryService/HGInventoryService.cs302
-rw-r--r--OpenSim/Services/InventoryService/InventoryService.cs4
-rw-r--r--OpenSim/Services/InventoryService/LibraryService.cs283
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs72
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs995
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs813
-rw-r--r--OpenSim/Services/PresenceService/PresenceService.cs102
-rw-r--r--OpenSim/Services/PresenceService/PresenceServiceBase.cs4
-rw-r--r--OpenSim/Services/UserAccountService/GridUserService.cs159
-rw-r--r--OpenSim/Services/UserAccountService/GridUserServiceBase.cs82
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountService.cs399
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountServiceBase.cs (renamed from OpenSim/Services/UserService/UserServiceBase.cs)19
62 files changed, 13015 insertions, 721 deletions
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index ed87f3f..470a4dd 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -106,7 +106,10 @@ namespace OpenSim.Services.AssetService
106 return null; 106 return null;
107 107
108 AssetBase asset = m_Database.GetAsset(assetID); 108 AssetBase asset = m_Database.GetAsset(assetID);
109 return asset.Metadata; 109 if (asset != null)
110 return asset.Metadata;
111
112 return null;
110 } 113 }
111 114
112 public byte[] GetData(string id) 115 public byte[] GetData(string id)
@@ -153,6 +156,22 @@ namespace OpenSim.Services.AssetService
153 156
154 public bool Delete(string id) 157 public bool Delete(string id)
155 { 158 {
159 m_log.DebugFormat("[ASSET SERVICE]: Deleting asset {0}", id);
160 UUID assetID;
161 if (!UUID.TryParse(id, out assetID))
162 return false;
163
164 AssetBase asset = m_Database.GetAsset(assetID);
165 if (asset == null)
166 return false;
167
168 if ((int)(asset.Flags & AssetFlags.Maptile) != 0)
169 {
170 return m_Database.Delete(id);
171 }
172 else
173 m_log.DebugFormat("[ASSET SERVICE]: Request to delete asset {0}, but flags are not Maptile", id);
174
156 return false; 175 return false;
157 } 176 }
158 177
@@ -178,6 +197,7 @@ namespace OpenSim.Services.AssetService
178 MainConsole.Instance.Output(String.Format("Description: {0}", asset.Description)); 197 MainConsole.Instance.Output(String.Format("Description: {0}", asset.Description));
179 MainConsole.Instance.Output(String.Format("Type: {0}", asset.Type)); 198 MainConsole.Instance.Output(String.Format("Type: {0}", asset.Type));
180 MainConsole.Instance.Output(String.Format("Content-type: {0}", asset.Metadata.ContentType)); 199 MainConsole.Instance.Output(String.Format("Content-type: {0}", asset.Metadata.ContentType));
200 MainConsole.Instance.Output(String.Format("Flags: {0}", asset.Metadata.Flags.ToString()));
181 201
182 for (i = 0 ; i < 5 ; i++) 202 for (i = 0 ; i < 5 ; i++)
183 { 203 {
diff --git a/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs b/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs
index dcf090e..9af61a9 100644
--- a/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs
+++ b/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs
@@ -32,6 +32,7 @@ using Nini.Config;
32using System.Reflection; 32using System.Reflection;
33using OpenSim.Services.Base; 33using OpenSim.Services.Base;
34using OpenSim.Data; 34using OpenSim.Data;
35using OpenSim.Framework;
35 36
36namespace OpenSim.Services.AuthenticationService 37namespace OpenSim.Services.AuthenticationService
37{ 38{
@@ -43,9 +44,9 @@ namespace OpenSim.Services.AuthenticationService
43 // 44 //
44 public class AuthenticationServiceBase : ServiceBase 45 public class AuthenticationServiceBase : ServiceBase
45 { 46 {
46// private static readonly ILog m_log = 47 private static readonly ILog m_log =
47// LogManager.GetLogger( 48 LogManager.GetLogger(
48// MethodBase.GetCurrentMethod().DeclaringType); 49 MethodBase.GetCurrentMethod().DeclaringType);
49 50
50 protected IAuthenticationData m_Database; 51 protected IAuthenticationData m_Database;
51 52
@@ -100,6 +101,32 @@ namespace OpenSim.Services.AuthenticationService
100 return m_Database.CheckToken(principalID, token, 0); 101 return m_Database.CheckToken(principalID, token, 0);
101 } 102 }
102 103
104 public virtual bool SetPassword(UUID principalID, string password)
105 {
106 string passwordSalt = Util.Md5Hash(UUID.Random().ToString());
107 string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + passwordSalt);
108
109 AuthenticationData auth = m_Database.Get(principalID);
110 if (auth == null)
111 {
112 auth = new AuthenticationData();
113 auth.PrincipalID = principalID;
114 auth.Data = new System.Collections.Generic.Dictionary<string, object>();
115 auth.Data["accountType"] = "UserAccount";
116 auth.Data["webLoginKey"] = UUID.Zero.ToString();
117 }
118 auth.Data["passwordHash"] = md5PasswdHash;
119 auth.Data["passwordSalt"] = passwordSalt;
120 if (!m_Database.Store(auth))
121 {
122 m_log.DebugFormat("[AUTHENTICATION DB]: Failed to store authentication data");
123 return false;
124 }
125
126 m_log.InfoFormat("[AUTHENTICATION DB]: Set password for principalID {0}", principalID);
127 return true;
128 }
129
103 protected string GetToken(UUID principalID, int lifetime) 130 protected string GetToken(UUID principalID, int lifetime)
104 { 131 {
105 UUID token = UUID.Random(); 132 UUID token = UUID.Random();
@@ -109,5 +136,6 @@ namespace OpenSim.Services.AuthenticationService
109 136
110 return String.Empty; 137 return String.Empty;
111 } 138 }
139
112 } 140 }
113} 141}
diff --git a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
index d65665a..2fc9248 100644
--- a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
+++ b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
@@ -47,9 +47,9 @@ namespace OpenSim.Services.AuthenticationService
47 public class PasswordAuthenticationService : 47 public class PasswordAuthenticationService :
48 AuthenticationServiceBase, IAuthenticationService 48 AuthenticationServiceBase, IAuthenticationService
49 { 49 {
50// private static readonly ILog m_log = 50 private static readonly ILog m_log =
51// LogManager.GetLogger( 51 LogManager.GetLogger(
52// MethodBase.GetCurrentMethod().DeclaringType); 52 MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 public PasswordAuthenticationService(IConfigSource config) : 54 public PasswordAuthenticationService(IConfigSource config) :
55 base(config) 55 base(config)
@@ -59,21 +59,27 @@ namespace OpenSim.Services.AuthenticationService
59 public string Authenticate(UUID principalID, string password, int lifetime) 59 public string Authenticate(UUID principalID, string password, int lifetime)
60 { 60 {
61 AuthenticationData data = m_Database.Get(principalID); 61 AuthenticationData data = m_Database.Get(principalID);
62 62
63 if (!data.Data.ContainsKey("passwordHash") || 63 if (data != null && data.Data != null)
64 !data.Data.ContainsKey("passwordSalt"))
65 { 64 {
66 return String.Empty; 65 if (!data.Data.ContainsKey("passwordHash") ||
67 } 66 !data.Data.ContainsKey("passwordSalt"))
67 {
68 return String.Empty;
69 }
68 70
69 string hashed = Util.Md5Hash(Util.Md5Hash(password) + ":" + 71 string hashed = Util.Md5Hash(password + ":" +
70 data.Data["passwordSalt"].ToString()); 72 data.Data["passwordSalt"].ToString());
71 73
72 if (data.Data["passwordHash"].ToString() == hashed) 74 //m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString());
73 { 75
74 return GetToken(principalID, lifetime); 76 if (data.Data["passwordHash"].ToString() == hashed)
77 {
78 return GetToken(principalID, lifetime);
79 }
75 } 80 }
76 81
82 m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID);
77 return String.Empty; 83 return String.Empty;
78 } 84 }
79 } 85 }
diff --git a/OpenSim/Services/AvatarService/AvatarService.cs b/OpenSim/Services/AvatarService/AvatarService.cs
new file mode 100644
index 0000000..19e662c
--- /dev/null
+++ b/OpenSim/Services/AvatarService/AvatarService.cs
@@ -0,0 +1,144 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using Nini.Config;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Framework.Console;
36using OpenSim.Data;
37using OpenSim.Services.Interfaces;
38using OpenMetaverse;
39
40namespace OpenSim.Services.AvatarService
41{
42 public class AvatarService : AvatarServiceBase, IAvatarService
43 {
44 private static readonly ILog m_log =
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
47
48 public AvatarService(IConfigSource config)
49 : base(config)
50 {
51 m_log.Debug("[AVATAR SERVICE]: Starting avatar service");
52 }
53
54 public AvatarData GetAvatar(UUID principalID)
55 {
56 AvatarBaseData[] av = m_Database.Get("PrincipalID", principalID.ToString());
57 if (av.Length == 0)
58 return null;
59
60 AvatarData ret = new AvatarData();
61 ret.Data = new Dictionary<string,string>();
62
63 foreach (AvatarBaseData b in av)
64 {
65 if (b.Data["Name"] == "AvatarType")
66 ret.AvatarType = Convert.ToInt32(b.Data["Value"]);
67 else
68 ret.Data[b.Data["Name"]] = b.Data["Value"];
69 }
70
71 return ret;
72 }
73
74 public bool SetAvatar(UUID principalID, AvatarData avatar)
75 {
76 int count = 0;
77 foreach (KeyValuePair<string, string> kvp in avatar.Data)
78 if (kvp.Key.StartsWith("_"))
79 count++;
80
81 m_log.DebugFormat("[AVATAR SERVICE]: SetAvatar for {0}, attachs={1}", principalID, count);
82 m_Database.Delete("PrincipalID", principalID.ToString());
83
84 AvatarBaseData av = new AvatarBaseData();
85 av.Data = new Dictionary<string,string>();
86
87 av.PrincipalID = principalID;
88 av.Data["Name"] = "AvatarType";
89 av.Data["Value"] = avatar.AvatarType.ToString();
90
91 if (!m_Database.Store(av))
92 return false;
93
94 foreach (KeyValuePair<string,string> kvp in avatar.Data)
95 {
96 av.Data["Name"] = kvp.Key;
97 av.Data["Value"] = kvp.Value;
98
99 if (!m_Database.Store(av))
100 {
101 m_Database.Delete("PrincipalID", principalID.ToString());
102 return false;
103 }
104 }
105
106 return true;
107 }
108
109 public bool ResetAvatar(UUID principalID)
110 {
111 return m_Database.Delete("PrincipalID", principalID.ToString());
112 }
113
114 public bool SetItems(UUID principalID, string[] names, string[] values)
115 {
116 AvatarBaseData av = new AvatarBaseData();
117 av.Data = new Dictionary<string,string>();
118 av.PrincipalID = principalID;
119
120 if (names.Length != values.Length)
121 return false;
122
123 for (int i = 0 ; i < names.Length ; i++)
124 {
125 av.Data["Name"] = names[i];
126 av.Data["Value"] = values[i];
127
128 if (!m_Database.Store(av))
129 return false;
130 }
131
132 return true;
133 }
134
135 public bool RemoveItems(UUID principalID, string[] names)
136 {
137 foreach (string name in names)
138 {
139 m_Database.Delete(principalID, name);
140 }
141 return true;
142 }
143 }
144}
diff --git a/OpenSim/Services/AvatarService/AvatarServiceBase.cs b/OpenSim/Services/AvatarService/AvatarServiceBase.cs
new file mode 100644
index 0000000..ab9d7cd
--- /dev/null
+++ b/OpenSim/Services/AvatarService/AvatarServiceBase.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
28using System;
29using System.Reflection;
30using Nini.Config;
31using OpenSim.Framework;
32using OpenSim.Data;
33using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base;
35
36namespace OpenSim.Services.AvatarService
37{
38 public class AvatarServiceBase : ServiceBase
39 {
40 protected IAvatarData m_Database = null;
41
42 public AvatarServiceBase(IConfigSource config)
43 : base(config)
44 {
45 string dllName = String.Empty;
46 string connString = String.Empty;
47 string realm = "Avatars";
48
49 //
50 // Try reading the [DatabaseService] section, if it exists
51 //
52 IConfig dbConfig = config.Configs["DatabaseService"];
53 if (dbConfig != null)
54 {
55 if (dllName == String.Empty)
56 dllName = dbConfig.GetString("StorageProvider", String.Empty);
57 if (connString == String.Empty)
58 connString = dbConfig.GetString("ConnectionString", String.Empty);
59 }
60
61 //
62 // [AvatarService] section overrides [DatabaseService], if it exists
63 //
64 IConfig presenceConfig = config.Configs["AvatarService"];
65 if (presenceConfig != null)
66 {
67 dllName = presenceConfig.GetString("StorageProvider", dllName);
68 connString = presenceConfig.GetString("ConnectionString", connString);
69 realm = presenceConfig.GetString("Realm", realm);
70 }
71
72 //
73 // We tried, but this doesn't exist. We can't proceed.
74 //
75 if (dllName.Equals(String.Empty))
76 throw new Exception("No StorageProvider configured");
77
78 m_Database = LoadPlugin<IAvatarData>(dllName, new Object[] { connString, realm });
79 if (m_Database == null)
80 throw new Exception("Could not find a storage interface in the given module " + dllName);
81
82 }
83 }
84}
diff --git a/OpenSim/Services/Base/ServiceBase.cs b/OpenSim/Services/Base/ServiceBase.cs
index 6bbe978..ef30cba 100644
--- a/OpenSim/Services/Base/ServiceBase.cs
+++ b/OpenSim/Services/Base/ServiceBase.cs
@@ -26,7 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
31using log4net;
30using Nini.Config; 32using Nini.Config;
31using OpenSim.Services.Interfaces; 33using OpenSim.Services.Interfaces;
32 34
@@ -34,6 +36,8 @@ namespace OpenSim.Services.Base
34{ 36{
35 public class ServiceBase 37 public class ServiceBase
36 { 38 {
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40
37 public T LoadPlugin<T>(string dllName) where T:class 41 public T LoadPlugin<T>(string dllName) where T:class
38 { 42 {
39 return LoadPlugin<T>(dllName, new Object[0]); 43 return LoadPlugin<T>(dllName, new Object[0]);
@@ -61,8 +65,12 @@ namespace OpenSim.Services.Base
61 { 65 {
62 Assembly pluginAssembly = Assembly.LoadFrom(dllName); 66 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
63 67
68// m_log.DebugFormat("[SERVICE BASE]: Found assembly {0}", dllName);
69
64 foreach (Type pluginType in pluginAssembly.GetTypes()) 70 foreach (Type pluginType in pluginAssembly.GetTypes())
65 { 71 {
72// m_log.DebugFormat("[SERVICE BASE]: Found type {0}", pluginType);
73
66 if (pluginType.IsPublic) 74 if (pluginType.IsPublic)
67 { 75 {
68 if (className != String.Empty && 76 if (className != String.Empty &&
@@ -84,8 +92,17 @@ namespace OpenSim.Services.Base
84 92
85 return null; 93 return null;
86 } 94 }
87 catch (Exception) 95 catch (Exception e)
88 { 96 {
97 List<string> strArgs = new List<string>();
98 foreach (Object arg in args)
99 strArgs.Add(arg.ToString());
100
101 m_log.Error(
102 string.Format(
103 "[SERVICE BASE]: Failed to load plugin {0} from {1} with args {2}",
104 interfaceName, dllName, string.Join(", ", strArgs.ToArray())), e);
105
89 return null; 106 return null;
90 } 107 }
91 } 108 }
@@ -94,4 +111,4 @@ namespace OpenSim.Services.Base
94 { 111 {
95 } 112 }
96 } 113 }
97} 114} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index 84fbcd3..65b3537 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Services.Connectors
68 IConfig assetConfig = source.Configs["AssetService"]; 68 IConfig assetConfig = source.Configs["AssetService"];
69 if (assetConfig == null) 69 if (assetConfig == null)
70 { 70 {
71 m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpanSim.ini"); 71 m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
72 throw new Exception("Asset connector init error"); 72 throw new Exception("Asset connector init error");
73 } 73 }
74 74
@@ -251,7 +251,7 @@ namespace OpenSim.Services.Connectors
251 if (metadata == null) 251 if (metadata == null)
252 return false; 252 return false;
253 253
254 asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type); 254 asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type, UUID.Zero.ToString());
255 asset.Metadata = metadata; 255 asset.Metadata = metadata;
256 } 256 }
257 asset.Data = data; 257 asset.Data = data;
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
index 19bb3e2..6f77a2d 100644
--- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Services.Connectors
67 IConfig assetConfig = source.Configs["AuthenticationService"]; 67 IConfig assetConfig = source.Configs["AuthenticationService"];
68 if (assetConfig == null) 68 if (assetConfig == null)
69 { 69 {
70 m_log.Error("[USER CONNECTOR]: AuthenticationService missing from OpanSim.ini"); 70 m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini");
71 throw new Exception("Authentication connector init error"); 71 throw new Exception("Authentication connector init error");
72 } 72 }
73 73
@@ -76,7 +76,7 @@ namespace OpenSim.Services.Connectors
76 76
77 if (serviceURI == String.Empty) 77 if (serviceURI == String.Empty)
78 { 78 {
79 m_log.Error("[USER CONNECTOR]: No Server URI named in section AuthenticationService"); 79 m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService");
80 throw new Exception("Authentication connector init error"); 80 throw new Exception("Authentication connector init error");
81 } 81 }
82 m_ServerURI = serviceURI; 82 m_ServerURI = serviceURI;
@@ -146,5 +146,11 @@ namespace OpenSim.Services.Connectors
146 146
147 return true; 147 return true;
148 } 148 }
149
150 public bool SetPassword(UUID principalID, string passwd)
151 {
152 // nope, we don't do this
153 return false;
154 }
149 } 155 }
150} 156}
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
new file mode 100644
index 0000000..96c05a9
--- /dev/null
+++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
@@ -0,0 +1,317 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using IAvatarService = OpenSim.Services.Interfaces.IAvatarService;
40using OpenSim.Server.Base;
41using OpenMetaverse;
42
43namespace OpenSim.Services.Connectors
44{
45 public class AvatarServicesConnector : IAvatarService
46 {
47 private static readonly ILog m_log =
48 LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private string m_ServerURI = String.Empty;
52
53 public AvatarServicesConnector()
54 {
55 }
56
57 public AvatarServicesConnector(string serverURI)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 }
61
62 public AvatarServicesConnector(IConfigSource source)
63 {
64 Initialise(source);
65 }
66
67 public virtual void Initialise(IConfigSource source)
68 {
69 IConfig gridConfig = source.Configs["AvatarService"];
70 if (gridConfig == null)
71 {
72 m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini");
73 throw new Exception("Avatar connector init error");
74 }
75
76 string serviceURI = gridConfig.GetString("AvatarServerURI",
77 String.Empty);
78
79 if (serviceURI == String.Empty)
80 {
81 m_log.Error("[AVATAR CONNECTOR]: No Server URI named in section AvatarService");
82 throw new Exception("Avatar connector init error");
83 }
84 m_ServerURI = serviceURI;
85 }
86
87
88 #region IAvatarService
89
90 public AvatarData GetAvatar(UUID userID)
91 {
92 Dictionary<string, object> sendData = new Dictionary<string, object>();
93 //sendData["SCOPEID"] = scopeID.ToString();
94 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
95 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
96 sendData["METHOD"] = "getavatar";
97
98 sendData["UserID"] = userID;
99
100 string reply = string.Empty;
101 string reqString = ServerUtils.BuildQueryString(sendData);
102 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
103 try
104 {
105 reply = SynchronousRestFormsRequester.MakeRequest("POST",
106 m_ServerURI + "/avatar",
107 reqString);
108 if (reply == null || (reply != null && reply == string.Empty))
109 {
110 m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply");
111 return null;
112 }
113 }
114 catch (Exception e)
115 {
116 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
117 }
118
119 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
120 AvatarData avatar = null;
121
122 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
123 {
124 if (replyData["result"] is Dictionary<string, object>)
125 {
126 avatar = new AvatarData((Dictionary<string, object>)replyData["result"]);
127 }
128 }
129
130 return avatar;
131
132 }
133
134 public bool SetAvatar(UUID userID, AvatarData avatar)
135 {
136 Dictionary<string, object> sendData = new Dictionary<string, object>();
137 //sendData["SCOPEID"] = scopeID.ToString();
138 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
139 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
140 sendData["METHOD"] = "setavatar";
141
142 sendData["UserID"] = userID.ToString();
143
144 Dictionary<string, object> structData = avatar.ToKeyValuePairs();
145
146 foreach (KeyValuePair<string, object> kvp in structData)
147 sendData[kvp.Key] = kvp.Value.ToString();
148
149
150 string reqString = ServerUtils.BuildQueryString(sendData);
151 //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
152 try
153 {
154 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
155 m_ServerURI + "/avatar",
156 reqString);
157 if (reply != string.Empty)
158 {
159 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
160
161 if (replyData.ContainsKey("result"))
162 {
163 if (replyData["result"].ToString().ToLower() == "success")
164 return true;
165 else
166 return false;
167 }
168 else
169 m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar reply data does not contain result field");
170
171 }
172 else
173 m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar received empty reply");
174 }
175 catch (Exception e)
176 {
177 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
178 }
179
180 return false;
181 }
182
183 public bool ResetAvatar(UUID userID)
184 {
185 Dictionary<string, object> sendData = new Dictionary<string, object>();
186 //sendData["SCOPEID"] = scopeID.ToString();
187 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
188 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
189 sendData["METHOD"] = "resetavatar";
190
191 sendData["UserID"] = userID.ToString();
192
193 string reqString = ServerUtils.BuildQueryString(sendData);
194 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
195 try
196 {
197 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
198 m_ServerURI + "/avatar",
199 reqString);
200 if (reply != string.Empty)
201 {
202 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
203
204 if (replyData.ContainsKey("result"))
205 {
206 if (replyData["result"].ToString().ToLower() == "success")
207 return true;
208 else
209 return false;
210 }
211 else
212 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field");
213
214 }
215 else
216 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply");
217 }
218 catch (Exception e)
219 {
220 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
221 }
222
223 return false;
224 }
225
226 public bool SetItems(UUID userID, string[] names, string[] values)
227 {
228 Dictionary<string, object> sendData = new Dictionary<string, object>();
229 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
230 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
231 sendData["METHOD"] = "setitems";
232
233 sendData["UserID"] = userID.ToString();
234 sendData["Names"] = new List<string>(names);
235 sendData["Values"] = new List<string>(values);
236
237 string reqString = ServerUtils.BuildQueryString(sendData);
238 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
239 try
240 {
241 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
242 m_ServerURI + "/avatar",
243 reqString);
244 if (reply != string.Empty)
245 {
246 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
247
248 if (replyData.ContainsKey("result"))
249 {
250 if (replyData["result"].ToString().ToLower() == "success")
251 return true;
252 else
253 return false;
254 }
255 else
256 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field");
257
258 }
259 else
260 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply");
261 }
262 catch (Exception e)
263 {
264 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
265 }
266
267 return false;
268 }
269
270 public bool RemoveItems(UUID userID, string[] names)
271 {
272 Dictionary<string, object> sendData = new Dictionary<string, object>();
273 //sendData["SCOPEID"] = scopeID.ToString();
274 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
275 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
276 sendData["METHOD"] = "removeitems";
277
278 sendData["UserID"] = userID.ToString();
279 sendData["Names"] = new List<string>(names);
280
281 string reqString = ServerUtils.BuildQueryString(sendData);
282 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
283 try
284 {
285 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
286 m_ServerURI + "/avatar",
287 reqString);
288 if (reply != string.Empty)
289 {
290 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
291
292 if (replyData.ContainsKey("result"))
293 {
294 if (replyData["result"].ToString().ToLower() == "success")
295 return true;
296 else
297 return false;
298 }
299 else
300 m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems reply data does not contain result field");
301
302 }
303 else
304 m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems received empty reply");
305 }
306 catch (Exception e)
307 {
308 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
309 }
310
311 return false;
312 }
313
314 #endregion
315
316 }
317}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
new file mode 100644
index 0000000..baefebd
--- /dev/null
+++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
@@ -0,0 +1,241 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace OpenSim.Services.Connectors
43{
44 public class FriendsServicesConnector : IFriendsService
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 FriendsServicesConnector()
53 {
54 }
55
56 public FriendsServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public FriendsServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig gridConfig = source.Configs["FriendsService"];
69 if (gridConfig == null)
70 {
71 m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini");
72 throw new Exception("Friends connector init error");
73 }
74
75 string serviceURI = gridConfig.GetString("FriendsServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService");
81 throw new Exception("Friends connector init error");
82 }
83 m_ServerURI = serviceURI;
84 }
85
86
87 #region IFriendsService
88
89 public FriendInfo[] GetFriends(UUID PrincipalID)
90 {
91 Dictionary<string, object> sendData = new Dictionary<string, object>();
92
93 sendData["PRINCIPALID"] = PrincipalID.ToString();
94 sendData["METHOD"] = "getfriends";
95
96 string reqString = ServerUtils.BuildQueryString(sendData);
97
98 try
99 {
100 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
101 m_ServerURI + "/friends",
102 reqString);
103 if (reply != string.Empty)
104 {
105 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
106
107 if (replyData != null)
108 {
109 if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null"))
110 {
111 return new FriendInfo[0];
112 }
113
114 List<FriendInfo> finfos = new List<FriendInfo>();
115 Dictionary<string, object>.ValueCollection finfosList = replyData.Values;
116 //m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count);
117 foreach (object f in finfosList)
118 {
119 if (f is Dictionary<string, object>)
120 {
121 FriendInfo finfo = new FriendInfo((Dictionary<string, object>)f);
122 finfos.Add(finfo);
123 }
124 else
125 m_log.DebugFormat("[FRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}",
126 PrincipalID, f.GetType());
127 }
128
129 // Success
130 return finfos.ToArray();
131 }
132
133 else
134 m_log.DebugFormat("[FRIENDS CONNECTOR]: GetFriends {0} received null response",
135 PrincipalID);
136
137 }
138 }
139 catch (Exception e)
140 {
141 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
142 }
143
144 return new FriendInfo[0];
145
146 }
147
148 public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
149 {
150 FriendInfo finfo = new FriendInfo();
151 finfo.PrincipalID = PrincipalID;
152 finfo.Friend = Friend;
153 finfo.MyFlags = flags;
154
155 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
156
157 sendData["METHOD"] = "storefriend";
158
159 string reqString = ServerUtils.BuildQueryString(sendData);
160
161 string reply = string.Empty;
162 try
163 {
164 reply = SynchronousRestFormsRequester.MakeRequest("POST",
165 m_ServerURI + "/friends",
166 ServerUtils.BuildQueryString(sendData));
167 }
168 catch (Exception e)
169 {
170 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
171 return false;
172 }
173
174 if (reply != string.Empty)
175 {
176 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
177
178 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
179 {
180 bool success = false;
181 Boolean.TryParse(replyData["Result"].ToString(), out success);
182 return success;
183 }
184 else
185 m_log.DebugFormat("[FRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
186 PrincipalID, Friend);
187 }
188 else
189 m_log.DebugFormat("[FRIENDS CONNECTOR]: StoreFriend received null reply");
190
191 return false;
192
193 }
194
195 public bool Delete(UUID PrincipalID, string Friend)
196 {
197 Dictionary<string, object> sendData = new Dictionary<string, object>();
198 sendData["PRINCIPALID"] = PrincipalID.ToString();
199 sendData["FRIENDS"] = Friend;
200 sendData["METHOD"] = "deletefriend";
201
202 string reqString = ServerUtils.BuildQueryString(sendData);
203
204 string reply = string.Empty;
205 try
206 {
207 reply = SynchronousRestFormsRequester.MakeRequest("POST",
208 m_ServerURI + "/friends",
209 ServerUtils.BuildQueryString(sendData));
210 }
211 catch (Exception e)
212 {
213 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
214 return false;
215 }
216
217 if (reply != string.Empty)
218 {
219 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
220
221 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
222 {
223 bool success = false;
224 Boolean.TryParse(replyData["Result"].ToString(), out success);
225 return success;
226 }
227 else
228 m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend {0} {1} received null response",
229 PrincipalID, Friend);
230 }
231 else
232 m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend received null reply");
233
234 return false;
235
236 }
237
238 #endregion
239
240 }
241}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
new file mode 100644
index 0000000..d7cb015
--- /dev/null
+++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
@@ -0,0 +1,167 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31
32using OpenSim.Services.Interfaces;
33using GridRegion = OpenSim.Services.Interfaces.GridRegion;
34using OpenSim.Server.Base;
35using OpenSim.Framework.Servers.HttpServer;
36
37using OpenMetaverse;
38using log4net;
39
40namespace OpenSim.Services.Connectors.Friends
41{
42 public class FriendsSimConnector
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 public bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message)
47 {
48 Dictionary<string, object> sendData = new Dictionary<string, object>();
49 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
50 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
51 sendData["METHOD"] = "friendship_offered";
52
53 sendData["FromID"] = userID.ToString();
54 sendData["ToID"] = friendID.ToString();
55 sendData["Message"] = message;
56
57 return Call(region, sendData);
58
59 }
60
61 public bool FriendshipApproved(GridRegion region, UUID userID, string userName, UUID friendID)
62 {
63 Dictionary<string, object> sendData = new Dictionary<string, object>();
64 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
65 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
66 sendData["METHOD"] = "friendship_approved";
67
68 sendData["FromID"] = userID.ToString();
69 sendData["FromName"] = userName;
70 sendData["ToID"] = friendID.ToString();
71
72 return Call(region, sendData);
73 }
74
75 public bool FriendshipDenied(GridRegion region, UUID userID, string userName, UUID friendID)
76 {
77 Dictionary<string, object> sendData = new Dictionary<string, object>();
78 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
79 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
80 sendData["METHOD"] = "friendship_denied";
81
82 sendData["FromID"] = userID.ToString();
83 sendData["FromName"] = userName;
84 sendData["ToID"] = friendID.ToString();
85
86 return Call(region, sendData);
87 }
88
89 public bool FriendshipTerminated(GridRegion region, UUID userID, UUID friendID)
90 {
91 Dictionary<string, object> sendData = new Dictionary<string, object>();
92 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
93 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
94 sendData["METHOD"] = "friendship_terminated";
95
96 sendData["FromID"] = userID.ToString();
97 sendData["ToID"] = friendID.ToString();
98
99 return Call(region, sendData);
100 }
101
102 public bool GrantRights(GridRegion region, UUID userID, UUID friendID, int userFlags, int rights)
103 {
104 Dictionary<string, object> sendData = new Dictionary<string, object>();
105 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
106 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
107 sendData["METHOD"] = "grant_rights";
108
109 sendData["FromID"] = userID.ToString();
110 sendData["ToID"] = friendID.ToString();
111 sendData["UserFlags"] = userFlags.ToString();
112 sendData["Rights"] = rights.ToString();
113
114 return Call(region, sendData);
115 }
116
117 public bool StatusNotify(GridRegion region, UUID userID, UUID friendID, bool online)
118 {
119 Dictionary<string, object> sendData = new Dictionary<string, object>();
120 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
121 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
122 sendData["METHOD"] = "status";
123
124 sendData["FromID"] = userID.ToString();
125 sendData["ToID"] = friendID.ToString();
126 sendData["Online"] = online.ToString();
127
128 return Call(region, sendData);
129 }
130
131 private bool Call(GridRegion region, Dictionary<string, object> sendData)
132 {
133 string reqString = ServerUtils.BuildQueryString(sendData);
134 // m_log.DebugFormat("[FRIENDS CONNECTOR]: queryString = {0}", reqString);
135 try
136 {
137 string url = "http://" + region.ExternalHostName + ":" + region.HttpPort;
138 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
139 url + "/friends",
140 reqString);
141 if (reply != string.Empty)
142 {
143 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
144
145 if (replyData.ContainsKey("RESULT"))
146 {
147 if (replyData["RESULT"].ToString().ToLower() == "true")
148 return true;
149 else
150 return false;
151 }
152 else
153 m_log.DebugFormat("[FRIENDS CONNECTOR]: reply data does not contain result field");
154
155 }
156 else
157 m_log.DebugFormat("[FRIENDS CONNECTOR]: received empty reply");
158 }
159 catch (Exception e)
160 {
161 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting remote sim: {0}", e.ToString());
162 }
163
164 return false;
165 }
166 }
167}
diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
index 04c7c53..0ec8912 100644
--- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
@@ -300,7 +300,7 @@ namespace OpenSim.Services.Connectors
300 if (replyData["result"] is Dictionary<string, object>) 300 if (replyData["result"] is Dictionary<string, object>)
301 rinfo = new GridRegion((Dictionary<string, object>)replyData["result"]); 301 rinfo = new GridRegion((Dictionary<string, object>)replyData["result"]);
302 else 302 else
303 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received invalid response", 303 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received no region",
304 scopeID, x, y); 304 scopeID, x, y);
305 } 305 }
306 else 306 else
@@ -391,9 +391,6 @@ namespace OpenSim.Services.Connectors
391 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r); 391 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
392 rinfos.Add(rinfo); 392 rinfos.Add(rinfo);
393 } 393 }
394 else
395 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionsByName {0}, {1}, {2} received invalid response",
396 scopeID, name, maxNumber);
397 } 394 }
398 } 395 }
399 else 396 else
@@ -460,6 +457,153 @@ namespace OpenSim.Services.Connectors
460 return rinfos; 457 return rinfos;
461 } 458 }
462 459
460 public List<GridRegion> GetDefaultRegions(UUID scopeID)
461 {
462 Dictionary<string, object> sendData = new Dictionary<string, object>();
463
464 sendData["SCOPEID"] = scopeID.ToString();
465
466 sendData["METHOD"] = "get_default_regions";
467
468 List<GridRegion> rinfos = new List<GridRegion>();
469 string reply = string.Empty;
470 try
471 {
472 reply = SynchronousRestFormsRequester.MakeRequest("POST",
473 m_ServerURI + "/grid",
474 ServerUtils.BuildQueryString(sendData));
475
476 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
477 }
478 catch (Exception e)
479 {
480 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
481 return rinfos;
482 }
483
484 if (reply != string.Empty)
485 {
486 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
487
488 if (replyData != null)
489 {
490 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
491 foreach (object r in rinfosList)
492 {
493 if (r is Dictionary<string, object>)
494 {
495 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
496 rinfos.Add(rinfo);
497 }
498 }
499 }
500 else
501 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions {0} received null response",
502 scopeID);
503 }
504 else
505 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions received null reply");
506
507 return rinfos;
508 }
509
510 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
511 {
512 Dictionary<string, object> sendData = new Dictionary<string, object>();
513
514 sendData["SCOPEID"] = scopeID.ToString();
515 sendData["X"] = x.ToString();
516 sendData["Y"] = y.ToString();
517
518 sendData["METHOD"] = "get_fallback_regions";
519
520 List<GridRegion> rinfos = new List<GridRegion>();
521 string reply = string.Empty;
522 try
523 {
524 reply = SynchronousRestFormsRequester.MakeRequest("POST",
525 m_ServerURI + "/grid",
526 ServerUtils.BuildQueryString(sendData));
527
528 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
529 }
530 catch (Exception e)
531 {
532 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
533 return rinfos;
534 }
535
536 if (reply != string.Empty)
537 {
538 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
539
540 if (replyData != null)
541 {
542 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
543 foreach (object r in rinfosList)
544 {
545 if (r is Dictionary<string, object>)
546 {
547 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
548 rinfos.Add(rinfo);
549 }
550 }
551 }
552 else
553 m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions {0}, {1}-{2} received null response",
554 scopeID, x, y);
555 }
556 else
557 m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions received null reply");
558
559 return rinfos;
560 }
561
562 public virtual int GetRegionFlags(UUID scopeID, UUID regionID)
563 {
564 Dictionary<string, object> sendData = new Dictionary<string, object>();
565
566 sendData["SCOPEID"] = scopeID.ToString();
567 sendData["REGIONID"] = regionID.ToString();
568
569 sendData["METHOD"] = "get_region_flags";
570
571 string reply = string.Empty;
572 try
573 {
574 reply = SynchronousRestFormsRequester.MakeRequest("POST",
575 m_ServerURI + "/grid",
576 ServerUtils.BuildQueryString(sendData));
577 }
578 catch (Exception e)
579 {
580 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
581 return -1;
582 }
583
584 int flags = -1;
585
586 if (reply != string.Empty)
587 {
588 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
589
590 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
591 {
592 Int32.TryParse((string)replyData["result"], out flags);
593 //else
594 // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received wrong type {2}",
595 // scopeID, regionID, replyData["result"].GetType());
596 }
597 else
598 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received null response",
599 scopeID, regionID);
600 }
601 else
602 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags received null reply");
603
604 return flags;
605 }
606
463 #endregion 607 #endregion
464 608
465 } 609 }
diff --git a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs
deleted file mode 100644
index 7098b07..0000000
--- a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs
+++ /dev/null
@@ -1,254 +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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Text;
32using System.Drawing;
33using System.Net;
34using System.Reflection;
35using OpenSim.Services.Interfaces;
36using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37
38using OpenSim.Framework;
39
40using OpenMetaverse;
41using OpenMetaverse.Imaging;
42using log4net;
43using Nwc.XmlRpc;
44
45namespace OpenSim.Services.Connectors.Grid
46{
47 public class HypergridServiceConnector
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IAssetService m_AssetService;
52
53 public HypergridServiceConnector(IAssetService assService)
54 {
55 m_AssetService = assService;
56 }
57
58 public UUID LinkRegion(GridRegion info, out ulong realHandle)
59 {
60 UUID uuid = UUID.Zero;
61 realHandle = 0;
62
63 Hashtable hash = new Hashtable();
64 hash["region_name"] = info.RegionName;
65
66 IList paramList = new ArrayList();
67 paramList.Add(hash);
68
69 XmlRpcRequest request = new XmlRpcRequest("link_region", paramList);
70 string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
71 m_log.Debug("[HGrid]: Linking to " + uri);
72 XmlRpcResponse response = null;
73 try
74 {
75 response = request.Send(uri, 10000);
76 }
77 catch (Exception e)
78 {
79 m_log.Debug("[HGrid]: Exception " + e.Message);
80 return uuid;
81 }
82
83 if (response.IsFault)
84 {
85 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
86 }
87 else
88 {
89 hash = (Hashtable)response.Value;
90 //foreach (Object o in hash)
91 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
92 try
93 {
94 UUID.TryParse((string)hash["uuid"], out uuid);
95 //m_log.Debug(">> HERE, uuid: " + uuid);
96 info.RegionID = uuid;
97 if ((string)hash["handle"] != null)
98 {
99 realHandle = Convert.ToUInt64((string)hash["handle"]);
100 //m_log.Debug(">> HERE, realHandle: " + realHandle);
101 }
102 //if (hash["region_image"] != null)
103 //{
104 // UUID img = UUID.Zero;
105 // UUID.TryParse((string)hash["region_image"], out img);
106 // info.RegionSettings.TerrainImageID = img;
107 //}
108 if (hash["region_name"] != null)
109 {
110 info.RegionName = (string)hash["region_name"];
111 //m_log.Debug(">> " + info.RegionName);
112 }
113 if (hash["internal_port"] != null)
114 {
115 int port = Convert.ToInt32((string)hash["internal_port"]);
116 info.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
117 //m_log.Debug(">> " + info.InternalEndPoint.ToString());
118 }
119
120 }
121 catch (Exception e)
122 {
123 m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace);
124 }
125 }
126 return uuid;
127 }
128
129 public void GetMapImage(GridRegion info)
130 {
131 try
132 {
133 string regionimage = "regionImage" + info.RegionID.ToString();
134 regionimage = regionimage.Replace("-", "");
135
136 WebClient c = new WebClient();
137 string uri = "http://" + info.ExternalHostName + ":" + info.HttpPort + "/index.php?method=" + regionimage;
138 //m_log.Debug("JPEG: " + uri);
139 c.DownloadFile(uri, info.RegionID.ToString() + ".jpg");
140 Bitmap m = new Bitmap(info.RegionID.ToString() + ".jpg");
141 //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
142 byte[] imageData = OpenJPEG.EncodeFromImage(m, true);
143 AssetBase ass = new AssetBase(UUID.Random(), "region " + info.RegionID.ToString(), (sbyte)AssetType.Texture);
144
145 // !!! for now
146 //info.RegionSettings.TerrainImageID = ass.FullID;
147
148 ass.Temporary = true;
149 ass.Local = true;
150 ass.Data = imageData;
151
152 m_AssetService.Store(ass);
153
154 // finally
155 info.TerrainImage = ass.FullID;
156
157 }
158 catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
159 {
160 m_log.Warn("[HGrid]: Failed getting/storing map image, because it is probably already in the cache");
161 }
162 }
163
164 public bool InformRegionOfUser(GridRegion regInfo, AgentCircuitData agentData, GridRegion home, string userServer, string assetServer, string inventoryServer)
165 {
166 string capsPath = agentData.CapsPath;
167 Hashtable loginParams = new Hashtable();
168 loginParams["session_id"] = agentData.SessionID.ToString();
169
170 loginParams["firstname"] = agentData.firstname;
171 loginParams["lastname"] = agentData.lastname;
172
173 loginParams["agent_id"] = agentData.AgentID.ToString();
174 loginParams["circuit_code"] = agentData.circuitcode.ToString();
175 loginParams["startpos_x"] = agentData.startpos.X.ToString();
176 loginParams["startpos_y"] = agentData.startpos.Y.ToString();
177 loginParams["startpos_z"] = agentData.startpos.Z.ToString();
178 loginParams["caps_path"] = capsPath;
179
180 if (home != null)
181 {
182 loginParams["region_uuid"] = home.RegionID.ToString();
183 loginParams["regionhandle"] = home.RegionHandle.ToString();
184 loginParams["home_address"] = home.ExternalHostName;
185 loginParams["home_port"] = home.HttpPort.ToString();
186 loginParams["internal_port"] = home.InternalEndPoint.Port.ToString();
187
188 m_log.Debug(" --------- Home -------");
189 m_log.Debug(" >> " + loginParams["home_address"] + " <<");
190 m_log.Debug(" >> " + loginParams["region_uuid"] + " <<");
191 m_log.Debug(" >> " + loginParams["regionhandle"] + " <<");
192 m_log.Debug(" >> " + loginParams["home_port"] + " <<");
193 m_log.Debug(" --------- ------------ -------");
194 }
195 else
196 m_log.WarnFormat("[HGrid]: Home region not found for {0} {1}", agentData.firstname, agentData.lastname);
197
198 loginParams["userserver_id"] = userServer;
199 loginParams["assetserver_id"] = assetServer;
200 loginParams["inventoryserver_id"] = inventoryServer;
201
202
203 ArrayList SendParams = new ArrayList();
204 SendParams.Add(loginParams);
205
206 // Send
207 string uri = "http://" + regInfo.ExternalHostName + ":" + regInfo.HttpPort + "/";
208 //m_log.Debug("XXX uri: " + uri);
209 XmlRpcRequest request = new XmlRpcRequest("expect_hg_user", SendParams);
210 XmlRpcResponse reply;
211 try
212 {
213 reply = request.Send(uri, 6000);
214 }
215 catch (Exception e)
216 {
217 m_log.Warn("[HGrid]: Failed to notify region about user. Reason: " + e.Message);
218 return false;
219 }
220
221 if (!reply.IsFault)
222 {
223 bool responseSuccess = true;
224 if (reply.Value != null)
225 {
226 Hashtable resp = (Hashtable)reply.Value;
227 if (resp.ContainsKey("success"))
228 {
229 if ((string)resp["success"] == "FALSE")
230 {
231 responseSuccess = false;
232 }
233 }
234 }
235 if (responseSuccess)
236 {
237 m_log.Info("[HGrid]: Successfully informed remote region about user " + agentData.AgentID);
238 return true;
239 }
240 else
241 {
242 m_log.ErrorFormat("[HGrid]: Region responded that it is not available to receive clients");
243 return false;
244 }
245 }
246 else
247 {
248 m_log.ErrorFormat("[HGrid]: XmlRpc request to region failed with message {0}, code {1} ", reply.FaultString, reply.FaultCode);
249 return false;
250 }
251 }
252
253 }
254}
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
new file mode 100644
index 0000000..b4500a5
--- /dev/null
+++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
@@ -0,0 +1,230 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace OpenSim.Services.Connectors
43{
44 public class GridUserServicesConnector : IGridUserService
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 GridUserServicesConnector()
53 {
54 }
55
56 public GridUserServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public GridUserServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig gridConfig = source.Configs["GridUserService"];
69 if (gridConfig == null)
70 {
71 m_log.Error("[GRID USER CONNECTOR]: GridUserService missing from OpenSim.ini");
72 throw new Exception("GridUser connector init error");
73 }
74
75 string serviceURI = gridConfig.GetString("GridUserServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[GRID USER CONNECTOR]: No Server URI named in section GridUserService");
81 throw new Exception("GridUser connector init error");
82 }
83 m_ServerURI = serviceURI;
84 }
85
86
87 #region IPresenceService
88
89
90 public GridUserInfo LoggedIn(string userID)
91 {
92 Dictionary<string, object> sendData = new Dictionary<string, object>();
93 //sendData["SCOPEID"] = scopeID.ToString();
94 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
95 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
96 sendData["METHOD"] = "loggedin";
97
98 sendData["UserID"] = userID;
99
100 return Get(sendData);
101
102 }
103
104 public bool LoggedOut(string userID, UUID region, Vector3 position, Vector3 lookat)
105 {
106 Dictionary<string, object> sendData = new Dictionary<string, object>();
107 //sendData["SCOPEID"] = scopeID.ToString();
108 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
109 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
110 sendData["METHOD"] = "loggedout";
111
112 return Set(sendData, userID, region, position, lookat);
113 }
114
115 public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
116 {
117 Dictionary<string, object> sendData = new Dictionary<string, object>();
118 //sendData["SCOPEID"] = scopeID.ToString();
119 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
120 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
121 sendData["METHOD"] = "sethome";
122
123 return Set(sendData, userID, regionID, position, lookAt);
124 }
125
126 public bool SetLastPosition(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
127 {
128 Dictionary<string, object> sendData = new Dictionary<string, object>();
129 //sendData["SCOPEID"] = scopeID.ToString();
130 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
131 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
132 sendData["METHOD"] = "setposition";
133
134 return Set(sendData, userID, regionID, position, lookAt);
135 }
136
137 public GridUserInfo GetGridUserInfo(string userID)
138 {
139 Dictionary<string, object> sendData = new Dictionary<string, object>();
140 //sendData["SCOPEID"] = scopeID.ToString();
141 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
142 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
143 sendData["METHOD"] = "getgriduserinfo";
144
145 sendData["UserID"] = userID;
146
147 return Get(sendData);
148 }
149
150 #endregion
151
152 protected bool Set(Dictionary<string, object> sendData, string userID, UUID regionID, Vector3 position, Vector3 lookAt)
153 {
154 sendData["UserID"] = userID;
155 sendData["RegionID"] = regionID.ToString();
156 sendData["Position"] = position.ToString();
157 sendData["LookAt"] = lookAt.ToString();
158
159 string reqString = ServerUtils.BuildQueryString(sendData);
160 // m_log.DebugFormat("[GRID USER CONNECTOR]: queryString = {0}", reqString);
161 try
162 {
163 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
164 m_ServerURI + "/griduser",
165 reqString);
166 if (reply != string.Empty)
167 {
168 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
169
170 if (replyData.ContainsKey("result"))
171 {
172 if (replyData["result"].ToString().ToLower() == "success")
173 return true;
174 else
175 return false;
176 }
177 else
178 m_log.DebugFormat("[GRID USER CONNECTOR]: SetPosition reply data does not contain result field");
179
180 }
181 else
182 m_log.DebugFormat("[GRID USER CONNECTOR]: SetPosition received empty reply");
183 }
184 catch (Exception e)
185 {
186 m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server: {0}", e.Message);
187 }
188
189 return false;
190 }
191
192 protected GridUserInfo Get(Dictionary<string, object> sendData)
193 {
194 string reqString = ServerUtils.BuildQueryString(sendData);
195 // m_log.DebugFormat("[GRID USER CONNECTOR]: queryString = {0}", reqString);
196 try
197 {
198 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
199 m_ServerURI + "/griduser",
200 reqString);
201 if (reply != string.Empty)
202 {
203 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
204 GridUserInfo guinfo = null;
205
206 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
207 {
208 if (replyData["result"] is Dictionary<string, object>)
209 {
210 guinfo = new GridUserInfo((Dictionary<string, object>)replyData["result"]);
211 }
212 }
213
214 return guinfo;
215
216 }
217 else
218 m_log.DebugFormat("[GRID USER CONNECTOR]: Loggedin received empty reply");
219 }
220 catch (Exception e)
221 {
222 m_log.DebugFormat("[GRID USER CONNECTOR]: Exception when contacting grid user server: {0}", e.Message);
223 }
224
225 return null;
226
227 }
228
229 }
230}
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
new file mode 100644
index 0000000..c426bba
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
@@ -0,0 +1,272 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Drawing;
32using System.Net;
33using System.Reflection;
34
35using OpenSim.Framework;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38
39using OpenMetaverse;
40using OpenMetaverse.Imaging;
41using Nwc.XmlRpc;
42using log4net;
43
44using OpenSim.Services.Connectors.Simulation;
45
46namespace OpenSim.Services.Connectors.Hypergrid
47{
48 public class GatekeeperServiceConnector : SimulationServiceConnector
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private static UUID m_HGMapImage = new UUID("00000000-0000-1111-9999-000000000013");
53
54 private IAssetService m_AssetService;
55
56 public GatekeeperServiceConnector() : base()
57 {
58 }
59
60 public GatekeeperServiceConnector(IAssetService assService)
61 {
62 m_AssetService = assService;
63 }
64
65 protected override string AgentPath()
66 {
67 return "/foreignagent/";
68 }
69
70 protected override string ObjectPath()
71 {
72 return "/foreignobject/";
73 }
74
75 public bool LinkRegion(GridRegion info, out UUID regionID, out ulong realHandle, out string externalName, out string imageURL, out string reason)
76 {
77 regionID = UUID.Zero;
78 imageURL = string.Empty;
79 realHandle = 0;
80 externalName = string.Empty;
81 reason = string.Empty;
82
83 Hashtable hash = new Hashtable();
84 hash["region_name"] = info.RegionName;
85
86 IList paramList = new ArrayList();
87 paramList.Add(hash);
88
89 XmlRpcRequest request = new XmlRpcRequest("link_region", paramList);
90 string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
91 //m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Linking to " + uri);
92 XmlRpcResponse response = null;
93 try
94 {
95 response = request.Send(uri, 10000);
96 }
97 catch (Exception e)
98 {
99 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Exception " + e.Message);
100 reason = "Error contacting remote server";
101 return false;
102 }
103
104 if (response.IsFault)
105 {
106 reason = response.FaultString;
107 m_log.ErrorFormat("[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}", response.FaultString);
108 return false;
109 }
110
111 hash = (Hashtable)response.Value;
112 //foreach (Object o in hash)
113 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
114 try
115 {
116 bool success = false;
117 Boolean.TryParse((string)hash["result"], out success);
118 if (success)
119 {
120 UUID.TryParse((string)hash["uuid"], out regionID);
121 //m_log.Debug(">> HERE, uuid: " + uuid);
122 if ((string)hash["handle"] != null)
123 {
124 realHandle = Convert.ToUInt64((string)hash["handle"]);
125 //m_log.Debug(">> HERE, realHandle: " + realHandle);
126 }
127 if (hash["region_image"] != null)
128 imageURL = (string)hash["region_image"];
129 if (hash["external_name"] != null)
130 externalName = (string)hash["external_name"];
131 }
132
133 }
134 catch (Exception e)
135 {
136 reason = "Error parsing return arguments";
137 m_log.Error("[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e.StackTrace);
138 return false;
139 }
140
141 return true;
142 }
143
144 UUID m_MissingTexture = new UUID("5748decc-f629-461c-9a36-a35a221fe21f");
145
146 public UUID GetMapImage(UUID regionID, string imageURL)
147 {
148 if (m_AssetService == null)
149 return m_MissingTexture;
150
151 try
152 {
153
154 WebClient c = new WebClient();
155 //m_log.Debug("JPEG: " + imageURL);
156 string filename = regionID.ToString();
157 c.DownloadFile(imageURL, filename + ".jpg");
158 Bitmap m = new Bitmap(filename + ".jpg");
159 //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
160 byte[] imageData = OpenJPEG.EncodeFromImage(m, true);
161 AssetBase ass = new AssetBase(UUID.Random(), "region " + filename, (sbyte)AssetType.Texture, regionID.ToString());
162
163 // !!! for now
164 //info.RegionSettings.TerrainImageID = ass.FullID;
165
166 ass.Temporary = true;
167 ass.Local = true;
168 ass.Data = imageData;
169
170 m_AssetService.Store(ass);
171
172 // finally
173 return ass.FullID;
174
175 }
176 catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
177 {
178 m_log.Warn("[GATEKEEPER SERVICE CONNECTOR]: Failed getting/storing map image, because it is probably already in the cache");
179 }
180 return UUID.Zero;
181 }
182
183 public GridRegion GetHyperlinkRegion(GridRegion gatekeeper, UUID regionID)
184 {
185 Hashtable hash = new Hashtable();
186 hash["region_uuid"] = regionID.ToString();
187
188 IList paramList = new ArrayList();
189 paramList.Add(hash);
190
191 XmlRpcRequest request = new XmlRpcRequest("get_region", paramList);
192 string uri = "http://" + gatekeeper.ExternalEndPoint.Address + ":" + gatekeeper.HttpPort + "/";
193 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: contacting " + uri);
194 XmlRpcResponse response = null;
195 try
196 {
197 response = request.Send(uri, 10000);
198 }
199 catch (Exception e)
200 {
201 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Exception " + e.Message);
202 return null;
203 }
204
205 if (response.IsFault)
206 {
207 m_log.ErrorFormat("[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}", response.FaultString);
208 return null;
209 }
210
211 hash = (Hashtable)response.Value;
212 //foreach (Object o in hash)
213 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
214 try
215 {
216 bool success = false;
217 Boolean.TryParse((string)hash["result"], out success);
218 if (success)
219 {
220 GridRegion region = new GridRegion();
221
222 UUID.TryParse((string)hash["uuid"], out region.RegionID);
223 //m_log.Debug(">> HERE, uuid: " + region.RegionID);
224 int n = 0;
225 if (hash["x"] != null)
226 {
227 Int32.TryParse((string)hash["x"], out n);
228 region.RegionLocX = n;
229 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
230 }
231 if (hash["y"] != null)
232 {
233 Int32.TryParse((string)hash["y"], out n);
234 region.RegionLocY = n;
235 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
236 }
237 if (hash["region_name"] != null)
238 {
239 region.RegionName = (string)hash["region_name"];
240 //m_log.Debug(">> HERE, name: " + region.RegionName);
241 }
242 if (hash["hostname"] != null)
243 region.ExternalHostName = (string)hash["hostname"];
244 if (hash["http_port"] != null)
245 {
246 uint p = 0;
247 UInt32.TryParse((string)hash["http_port"], out p);
248 region.HttpPort = p;
249 }
250 if (hash["internal_port"] != null)
251 {
252 int p = 0;
253 Int32.TryParse((string)hash["internal_port"], out p);
254 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
255 }
256
257 // Successful return
258 return region;
259 }
260
261 }
262 catch (Exception e)
263 {
264 m_log.Error("[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e.StackTrace);
265 return null;
266 }
267
268 return null;
269 }
270
271 }
272}
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
new file mode 100644
index 0000000..42eca05
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -0,0 +1,402 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using System.Text;
35
36using OpenSim.Framework;
37using OpenSim.Services.Interfaces;
38using OpenSim.Services.Connectors.Simulation;
39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
40
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
43using log4net;
44using Nwc.XmlRpc;
45using Nini.Config;
46
47namespace OpenSim.Services.Connectors.Hypergrid
48{
49 public class UserAgentServiceConnector : IUserAgentService
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(
53 MethodBase.GetCurrentMethod().DeclaringType);
54
55 string m_ServerURL;
56 public UserAgentServiceConnector(string url)
57 {
58 m_ServerURL = url;
59 }
60
61 public UserAgentServiceConnector(IConfigSource config)
62 {
63 }
64
65 public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason)
66 {
67 reason = String.Empty;
68
69 if (destination == null)
70 {
71 reason = "Destination is null";
72 m_log.Debug("[USER AGENT CONNECTOR]: Given destination is null");
73 return false;
74 }
75
76 string uri = m_ServerURL + "/homeagent/" + aCircuit.AgentID + "/";
77
78 Console.WriteLine(" >>> LoginAgentToGrid <<< " + uri);
79
80 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
81 AgentCreateRequest.Method = "POST";
82 AgentCreateRequest.ContentType = "application/json";
83 AgentCreateRequest.Timeout = 10000;
84 //AgentCreateRequest.KeepAlive = false;
85 //AgentCreateRequest.Headers.Add("Authorization", authKey);
86
87 // Fill it in
88 OSDMap args = PackCreateAgentArguments(aCircuit, gatekeeper, destination);
89
90 string strBuffer = "";
91 byte[] buffer = new byte[1];
92 try
93 {
94 strBuffer = OSDParser.SerializeJsonString(args);
95 Encoding str = Util.UTF8;
96 buffer = str.GetBytes(strBuffer);
97
98 }
99 catch (Exception e)
100 {
101 m_log.WarnFormat("[USER AGENT CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
102 // ignore. buffer will be empty, caller should check.
103 }
104
105 Stream os = null;
106 try
107 { // send the Post
108 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
109 os = AgentCreateRequest.GetRequestStream();
110 os.Write(buffer, 0, strBuffer.Length); //Send it
111 m_log.InfoFormat("[USER AGENT CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
112 uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
113 }
114 //catch (WebException ex)
115 catch
116 {
117 //m_log.InfoFormat("[USER AGENT CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
118 reason = "cannot contact remote region";
119 return false;
120 }
121 finally
122 {
123 if (os != null)
124 os.Close();
125 }
126
127 // Let's wait for the response
128 //m_log.Info("[USER AGENT CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
129
130 WebResponse webResponse = null;
131 StreamReader sr = null;
132 try
133 {
134 webResponse = AgentCreateRequest.GetResponse();
135 if (webResponse == null)
136 {
137 m_log.Info("[USER AGENT CONNECTOR]: Null reply on DoCreateChildAgentCall post");
138 }
139 else
140 {
141
142 sr = new StreamReader(webResponse.GetResponseStream());
143 string response = sr.ReadToEnd().Trim();
144 m_log.InfoFormat("[USER AGENT CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
145
146 if (!String.IsNullOrEmpty(response))
147 {
148 try
149 {
150 // we assume we got an OSDMap back
151 OSDMap r = Util.GetOSDMap(response);
152 bool success = r["success"].AsBoolean();
153 reason = r["reason"].AsString();
154 return success;
155 }
156 catch (NullReferenceException e)
157 {
158 m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
159
160 // check for old style response
161 if (response.ToLower().StartsWith("true"))
162 return true;
163
164 return false;
165 }
166 }
167 }
168 }
169 catch (WebException ex)
170 {
171 m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
172 reason = "Destination did not reply";
173 return false;
174 }
175 finally
176 {
177 if (sr != null)
178 sr.Close();
179 }
180
181 return true;
182
183 }
184
185 protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination)
186 {
187 OSDMap args = null;
188 try
189 {
190 args = aCircuit.PackAgentCircuitData();
191 }
192 catch (Exception e)
193 {
194 m_log.Debug("[USER AGENT CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
195 }
196 // Add the input arguments
197 args["gatekeeper_host"] = OSD.FromString(gatekeeper.ExternalHostName);
198 args["gatekeeper_port"] = OSD.FromString(gatekeeper.HttpPort.ToString());
199 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
200 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
201 args["destination_name"] = OSD.FromString(destination.RegionName);
202 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
203
204 return args;
205 }
206
207 public void SetClientToken(UUID sessionID, string token)
208 {
209 // no-op
210 }
211
212 public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
213 {
214 position = Vector3.UnitY; lookAt = Vector3.UnitY;
215
216 Hashtable hash = new Hashtable();
217 hash["userID"] = userID.ToString();
218
219 IList paramList = new ArrayList();
220 paramList.Add(hash);
221
222 XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList);
223 XmlRpcResponse response = null;
224 try
225 {
226 response = request.Send(m_ServerURL, 10000);
227 }
228 catch (Exception e)
229 {
230 return null;
231 }
232
233 if (response.IsFault)
234 {
235 return null;
236 }
237
238 hash = (Hashtable)response.Value;
239 //foreach (Object o in hash)
240 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
241 try
242 {
243 bool success = false;
244 Boolean.TryParse((string)hash["result"], out success);
245 if (success)
246 {
247 GridRegion region = new GridRegion();
248
249 UUID.TryParse((string)hash["uuid"], out region.RegionID);
250 //m_log.Debug(">> HERE, uuid: " + region.RegionID);
251 int n = 0;
252 if (hash["x"] != null)
253 {
254 Int32.TryParse((string)hash["x"], out n);
255 region.RegionLocX = n;
256 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
257 }
258 if (hash["y"] != null)
259 {
260 Int32.TryParse((string)hash["y"], out n);
261 region.RegionLocY = n;
262 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
263 }
264 if (hash["region_name"] != null)
265 {
266 region.RegionName = (string)hash["region_name"];
267 //m_log.Debug(">> HERE, name: " + region.RegionName);
268 }
269 if (hash["hostname"] != null)
270 region.ExternalHostName = (string)hash["hostname"];
271 if (hash["http_port"] != null)
272 {
273 uint p = 0;
274 UInt32.TryParse((string)hash["http_port"], out p);
275 region.HttpPort = p;
276 }
277 if (hash["internal_port"] != null)
278 {
279 int p = 0;
280 Int32.TryParse((string)hash["internal_port"], out p);
281 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
282 }
283 if (hash["position"] != null)
284 Vector3.TryParse((string)hash["position"], out position);
285 if (hash["lookAt"] != null)
286 Vector3.TryParse((string)hash["lookAt"], out lookAt);
287
288 // Successful return
289 return region;
290 }
291
292 }
293 catch (Exception e)
294 {
295 return null;
296 }
297
298 return null;
299
300 }
301
302 public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName)
303 {
304 Hashtable hash = new Hashtable();
305 hash["sessionID"] = sessionID.ToString();
306 hash["externalName"] = thisGridExternalName;
307
308 IList paramList = new ArrayList();
309 paramList.Add(hash);
310
311 XmlRpcRequest request = new XmlRpcRequest("agent_is_coming_home", paramList);
312 string reason = string.Empty;
313 return GetBoolResponse(request, out reason);
314 }
315
316 public bool VerifyAgent(UUID sessionID, string token)
317 {
318 Hashtable hash = new Hashtable();
319 hash["sessionID"] = sessionID.ToString();
320 hash["token"] = token;
321
322 IList paramList = new ArrayList();
323 paramList.Add(hash);
324
325 XmlRpcRequest request = new XmlRpcRequest("verify_agent", paramList);
326 string reason = string.Empty;
327 return GetBoolResponse(request, out reason);
328 }
329
330 public bool VerifyClient(UUID sessionID, string token)
331 {
332 Hashtable hash = new Hashtable();
333 hash["sessionID"] = sessionID.ToString();
334 hash["token"] = token;
335
336 IList paramList = new ArrayList();
337 paramList.Add(hash);
338
339 XmlRpcRequest request = new XmlRpcRequest("verify_client", paramList);
340 string reason = string.Empty;
341 return GetBoolResponse(request, out reason);
342 }
343
344 public void LogoutAgent(UUID userID, UUID sessionID)
345 {
346 Hashtable hash = new Hashtable();
347 hash["sessionID"] = sessionID.ToString();
348 hash["userID"] = userID.ToString();
349
350 IList paramList = new ArrayList();
351 paramList.Add(hash);
352
353 XmlRpcRequest request = new XmlRpcRequest("logout_agent", paramList);
354 string reason = string.Empty;
355 GetBoolResponse(request, out reason);
356 }
357
358
359 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
360 {
361 //m_log.Debug("[HGrid]: Linking to " + uri);
362 XmlRpcResponse response = null;
363 try
364 {
365 response = request.Send(m_ServerURL, 10000);
366 }
367 catch (Exception e)
368 {
369 m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server ");
370 reason = "Exception: " + e.Message;
371 return false;
372 }
373
374 if (response.IsFault)
375 {
376 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
377 reason = "XMLRPC Fault";
378 return false;
379 }
380
381 Hashtable hash = (Hashtable)response.Value;
382 //foreach (Object o in hash)
383 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
384 try
385 {
386 bool success = false;
387 reason = string.Empty;
388 Boolean.TryParse((string)hash["result"], out success);
389
390 return success;
391 }
392 catch (Exception e)
393 {
394 m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace);
395 reason = "Exception: " + e.Message;
396 return false;
397 }
398
399 }
400
401 }
402}
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
index b9ccd7e..e25e7eb 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Services.Connectors
68 IConfig assetConfig = source.Configs["InventoryService"]; 68 IConfig assetConfig = source.Configs["InventoryService"];
69 if (assetConfig == null) 69 if (assetConfig == null)
70 { 70 {
71 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpanSim.ini"); 71 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
72 throw new Exception("Inventory connector init error"); 72 throw new Exception("Inventory connector init error");
73 } 73 }
74 74
@@ -92,6 +92,8 @@ namespace OpenSim.Services.Connectors
92 92
93 if (ret == null) 93 if (ret == null)
94 return false; 94 return false;
95 if (ret.Count == 0)
96 return false;
95 97
96 return bool.Parse(ret["RESULT"].ToString()); 98 return bool.Parse(ret["RESULT"].ToString());
97 } 99 }
@@ -105,11 +107,20 @@ namespace OpenSim.Services.Connectors
105 107
106 if (ret == null) 108 if (ret == null)
107 return null; 109 return null;
110 if (ret.Count == 0)
111 return null;
108 112
109 List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); 113 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
110 114
111 foreach (Object o in ret.Values) 115 try
112 folders.Add(BuildFolder((Dictionary<string,object>)o)); 116 {
117 foreach (Object o in ret.Values)
118 folders.Add(BuildFolder((Dictionary<string, object>)o));
119 }
120 catch (Exception e)
121 {
122 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message);
123 }
113 124
114 return folders; 125 return folders;
115 } 126 }
@@ -123,11 +134,10 @@ namespace OpenSim.Services.Connectors
123 134
124 if (ret == null) 135 if (ret == null)
125 return null; 136 return null;
126
127 if (ret.Count == 0) 137 if (ret.Count == 0)
128 return null; 138 return null;
129 139
130 return BuildFolder(ret); 140 return BuildFolder((Dictionary<string, object>)ret["folder"]);
131 } 141 }
132 142
133 public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 143 public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
@@ -140,49 +150,55 @@ namespace OpenSim.Services.Connectors
140 150
141 if (ret == null) 151 if (ret == null)
142 return null; 152 return null;
143
144 if (ret.Count == 0) 153 if (ret.Count == 0)
145 return null; 154 return null;
146 155
147 return BuildFolder(ret); 156 return BuildFolder((Dictionary<string, object>)ret["folder"]);
148 } 157 }
149 158
150 public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) 159 public InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
151 { 160 {
152 Dictionary<string,object> ret = MakeRequest("GETFOLDERCONTENT",
153 new Dictionary<string,object> {
154 { "PRINCIPAL", principalID.ToString() },
155 { "FOLDER", folderID.ToString() }
156 });
157
158 if (ret == null)
159 return null;
160
161 if (ret.Count == 0)
162 return null;
163
164
165 InventoryCollection inventory = new InventoryCollection(); 161 InventoryCollection inventory = new InventoryCollection();
166 inventory.Folders = new List<InventoryFolderBase>();
167 inventory.Items = new List<InventoryItemBase>();
168 inventory.UserID = principalID;
169 162
170 Dictionary<string,object> folders = 163 try
171 (Dictionary<string,object>)ret["FOLDERS"]; 164 {
172 Dictionary<string,object> items = 165 Dictionary<string,object> ret = MakeRequest("GETFOLDERCONTENT",
173 (Dictionary<string,object>)ret["ITEMS"]; 166 new Dictionary<string,object> {
174 167 { "PRINCIPAL", principalID.ToString() },
175 foreach (Object o in folders.Values) 168 { "FOLDER", folderID.ToString() }
176 inventory.Folders.Add(BuildFolder((Dictionary<string,object>)o)); 169 });
177 foreach (Object o in items.Values) 170
178 inventory.Items.Add(BuildItem((Dictionary<string,object>)o)); 171 if (ret == null)
172 return null;
173 if (ret.Count == 0)
174 return null;
175
176
177 inventory.Folders = new List<InventoryFolderBase>();
178 inventory.Items = new List<InventoryItemBase>();
179 inventory.UserID = principalID;
180
181 Dictionary<string,object> folders =
182 (Dictionary<string,object>)ret["FOLDERS"];
183 Dictionary<string,object> items =
184 (Dictionary<string,object>)ret["ITEMS"];
185
186 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
187 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
188 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
189 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
190 }
191 catch (Exception e)
192 {
193 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolderContent: {0}", e.Message);
194 }
179 195
180 return inventory; 196 return inventory;
181 } 197 }
182 198
183 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 199 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
184 { 200 {
185 Dictionary<string,object> ret = MakeRequest("GETFOLDERCONTENT", 201 Dictionary<string,object> ret = MakeRequest("GETFOLDERITEMS",
186 new Dictionary<string,object> { 202 new Dictionary<string,object> {
187 { "PRINCIPAL", principalID.ToString() }, 203 { "PRINCIPAL", principalID.ToString() },
188 { "FOLDER", folderID.ToString() } 204 { "FOLDER", folderID.ToString() }
@@ -190,17 +206,15 @@ namespace OpenSim.Services.Connectors
190 206
191 if (ret == null) 207 if (ret == null)
192 return null; 208 return null;
193
194 if (ret.Count == 0) 209 if (ret.Count == 0)
195 return null; 210 return null;
196 211
197 212 Dictionary<string, object> items = (Dictionary<string, object>)ret["ITEMS"];
198 List<InventoryItemBase> items = new List<InventoryItemBase>(); 213 List<InventoryItemBase> fitems = new List<InventoryItemBase>();
199 214 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
200 foreach (Object o in ret.Values) 215 fitems.Add(BuildItem((Dictionary<string, object>)o));
201 items.Add(BuildItem((Dictionary<string,object>)o));
202 216
203 return items; 217 return fitems;
204 } 218 }
205 219
206 public bool AddFolder(InventoryFolderBase folder) 220 public bool AddFolder(InventoryFolderBase folder)
@@ -244,7 +258,8 @@ namespace OpenSim.Services.Connectors
244 Dictionary<string,object> ret = MakeRequest("MOVEFOLDER", 258 Dictionary<string,object> ret = MakeRequest("MOVEFOLDER",
245 new Dictionary<string,object> { 259 new Dictionary<string,object> {
246 { "ParentID", folder.ParentID.ToString() }, 260 { "ParentID", folder.ParentID.ToString() },
247 { "ID", folder.ID.ToString() } 261 { "ID", folder.ID.ToString() },
262 { "PRINCIPAL", folder.Owner.ToString() }
248 }); 263 });
249 264
250 if (ret == null) 265 if (ret == null)
@@ -362,7 +377,7 @@ namespace OpenSim.Services.Connectors
362 377
363 Dictionary<string,object> ret = MakeRequest("MOVEITEMS", 378 Dictionary<string,object> ret = MakeRequest("MOVEITEMS",
364 new Dictionary<string,object> { 379 new Dictionary<string,object> {
365 { "PrincipalID", principalID.ToString() }, 380 { "PRINCIPAL", principalID.ToString() },
366 { "IDLIST", idlist }, 381 { "IDLIST", idlist },
367 { "DESTLIST", destlist } 382 { "DESTLIST", destlist }
368 }); 383 });
@@ -394,34 +409,50 @@ namespace OpenSim.Services.Connectors
394 409
395 public InventoryItemBase GetItem(InventoryItemBase item) 410 public InventoryItemBase GetItem(InventoryItemBase item)
396 { 411 {
397 Dictionary<string,object> ret = MakeRequest("GETITEM", 412 try
398 new Dictionary<string,object> { 413 {
414 Dictionary<string, object> ret = MakeRequest("GETITEM",
415 new Dictionary<string, object> {
399 { "ID", item.ID.ToString() } 416 { "ID", item.ID.ToString() }
400 }); 417 });
401 418
402 if (ret == null) 419 if (ret == null)
403 return null; 420 return null;
421 if (ret.Count == 0)
422 return null;
404 423
405 if (ret.Count == 0) 424 return BuildItem((Dictionary<string, object>)ret["item"]);
406 return null; 425 }
426 catch (Exception e)
427 {
428 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetItem: {0}", e.Message);
429 }
407 430
408 return BuildItem(ret); 431 return null;
409 } 432 }
410 433
411 public InventoryFolderBase GetFolder(InventoryFolderBase folder) 434 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
412 { 435 {
413 Dictionary<string,object> ret = MakeRequest("GETFOLDER", 436 try
414 new Dictionary<string,object> { 437 {
438 Dictionary<string, object> ret = MakeRequest("GETFOLDER",
439 new Dictionary<string, object> {
415 { "ID", folder.ID.ToString() } 440 { "ID", folder.ID.ToString() }
416 }); 441 });
417 442
418 if (ret == null) 443 if (ret == null)
419 return null; 444 return null;
445 if (ret.Count == 0)
446 return null;
420 447
421 if (ret.Count == 0) 448 return BuildFolder((Dictionary<string, object>)ret["folder"]);
422 return null; 449 }
450 catch (Exception e)
451 {
452 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolder: {0}", e.Message);
453 }
423 454
424 return BuildFolder(ret); 455 return null;
425 } 456 }
426 457
427 public List<InventoryItemBase> GetActiveGestures(UUID principalID) 458 public List<InventoryItemBase> GetActiveGestures(UUID principalID)
@@ -436,8 +467,8 @@ namespace OpenSim.Services.Connectors
436 467
437 List<InventoryItemBase> items = new List<InventoryItemBase>(); 468 List<InventoryItemBase> items = new List<InventoryItemBase>();
438 469
439 foreach (Object o in ret.Values) 470 foreach (Object o in ret.Values) // getting the values directly, we don't care about the keys item_i
440 items.Add(BuildItem((Dictionary<string,object>)o)); 471 items.Add(BuildItem((Dictionary<string, object>)o));
441 472
442 return items; 473 return items;
443 } 474 }
@@ -494,13 +525,20 @@ namespace OpenSim.Services.Connectors
494 { 525 {
495 InventoryFolderBase folder = new InventoryFolderBase(); 526 InventoryFolderBase folder = new InventoryFolderBase();
496 527
497 folder.ParentID = new UUID(data["ParentID"].ToString()); 528 try
498 folder.Type = short.Parse(data["Type"].ToString()); 529 {
499 folder.Version = ushort.Parse(data["Version"].ToString()); 530 folder.ParentID = new UUID(data["ParentID"].ToString());
500 folder.Name = data["Name"].ToString(); 531 folder.Type = short.Parse(data["Type"].ToString());
501 folder.Owner = new UUID(data["Owner"].ToString()); 532 folder.Version = ushort.Parse(data["Version"].ToString());
502 folder.ID = new UUID(data["ID"].ToString()); 533 folder.Name = data["Name"].ToString();
503 534 folder.Owner = new UUID(data["Owner"].ToString());
535 folder.ID = new UUID(data["ID"].ToString());
536 }
537 catch (Exception e)
538 {
539 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building folder: {0}", e.Message);
540 }
541
504 return folder; 542 return folder;
505 } 543 }
506 544
@@ -508,28 +546,36 @@ namespace OpenSim.Services.Connectors
508 { 546 {
509 InventoryItemBase item = new InventoryItemBase(); 547 InventoryItemBase item = new InventoryItemBase();
510 548
511 item.AssetID = new UUID(data["AssetID"].ToString()); 549 try
512 item.AssetType = int.Parse(data["AssetType"].ToString()); 550 {
513 item.Name = data["Name"].ToString(); 551 item.AssetID = new UUID(data["AssetID"].ToString());
514 item.Owner = new UUID(data["Owner"].ToString()); 552 item.AssetType = int.Parse(data["AssetType"].ToString());
515 item.ID = new UUID(data["ID"].ToString()); 553 item.Name = data["Name"].ToString();
516 item.InvType = int.Parse(data["InvType"].ToString()); 554 item.Owner = new UUID(data["Owner"].ToString());
517 item.Folder = new UUID(data["Folder"].ToString()); 555 item.ID = new UUID(data["ID"].ToString());
518 item.CreatorId = data["CreatorId"].ToString(); 556 item.InvType = int.Parse(data["InvType"].ToString());
519 item.Description = data["Description"].ToString(); 557 item.Folder = new UUID(data["Folder"].ToString());
520 item.NextPermissions = uint.Parse(data["NextPermissions"].ToString()); 558 item.CreatorId = data["CreatorId"].ToString();
521 item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString()); 559 item.Description = data["Description"].ToString();
522 item.BasePermissions = uint.Parse(data["BasePermissions"].ToString()); 560 item.NextPermissions = uint.Parse(data["NextPermissions"].ToString());
523 item.EveryOnePermissions = uint.Parse(data["EveryOnePermissions"].ToString()); 561 item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString());
524 item.GroupPermissions = uint.Parse(data["GroupPermissions"].ToString()); 562 item.BasePermissions = uint.Parse(data["BasePermissions"].ToString());
525 item.GroupID = new UUID(data["GroupID"].ToString()); 563 item.EveryOnePermissions = uint.Parse(data["EveryOnePermissions"].ToString());
526 item.GroupOwned = bool.Parse(data["GroupOwned"].ToString()); 564 item.GroupPermissions = uint.Parse(data["GroupPermissions"].ToString());
527 item.SalePrice = int.Parse(data["SalePrice"].ToString()); 565 item.GroupID = new UUID(data["GroupID"].ToString());
528 item.SaleType = byte.Parse(data["SaleType"].ToString()); 566 item.GroupOwned = bool.Parse(data["GroupOwned"].ToString());
529 item.Flags = uint.Parse(data["Flags"].ToString()); 567 item.SalePrice = int.Parse(data["SalePrice"].ToString());
530 item.CreationDate = int.Parse(data["CreationDate"].ToString()); 568 item.SaleType = byte.Parse(data["SaleType"].ToString());
569 item.Flags = uint.Parse(data["Flags"].ToString());
570 item.CreationDate = int.Parse(data["CreationDate"].ToString());
571 }
572 catch (Exception e)
573 {
574 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building item: {0}", e.Message);
575 }
531 576
532 return item; 577 return item;
533 } 578 }
579
534 } 580 }
535} 581}
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
new file mode 100644
index 0000000..9f86078
--- /dev/null
+++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
@@ -0,0 +1,381 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace 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)
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
232 string reqString = ServerUtils.BuildQueryString(sendData);
233 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
234 try
235 {
236 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
237 m_ServerURI + "/presence",
238 reqString);
239 if (reply != string.Empty)
240 {
241 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
242
243 if (replyData.ContainsKey("result"))
244 {
245 if (replyData["result"].ToString().ToLower() == "success")
246 return true;
247 else
248 return false;
249 }
250 else
251 m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent reply data does not contain result field");
252
253 }
254 else
255 m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent received empty reply");
256 }
257 catch (Exception e)
258 {
259 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
260 }
261
262 return false;
263 }
264
265 public PresenceInfo GetAgent(UUID sessionID)
266 {
267 Dictionary<string, object> sendData = new Dictionary<string, object>();
268 //sendData["SCOPEID"] = scopeID.ToString();
269 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
270 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
271 sendData["METHOD"] = "getagent";
272
273 sendData["SessionID"] = sessionID.ToString();
274
275 string reply = string.Empty;
276 string reqString = ServerUtils.BuildQueryString(sendData);
277 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
278 try
279 {
280 reply = SynchronousRestFormsRequester.MakeRequest("POST",
281 m_ServerURI + "/presence",
282 reqString);
283 if (reply == null || (reply != null && reply == string.Empty))
284 {
285 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply");
286 return null;
287 }
288 }
289 catch (Exception e)
290 {
291 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
292 }
293
294 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
295 PresenceInfo pinfo = null;
296
297 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
298 {
299 if (replyData["result"] is Dictionary<string, object>)
300 {
301 pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]);
302 }
303 else
304 {
305 m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply (result not dictionary) received from presence server when querying for sessionID {0}", sessionID.ToString());
306 }
307 }
308 else
309 {
310 m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply received from presence server when querying for sessionID {0}", sessionID.ToString());
311 }
312
313 return pinfo;
314 }
315
316 public PresenceInfo[] GetAgents(string[] userIDs)
317 {
318 Dictionary<string, object> sendData = new Dictionary<string, object>();
319 //sendData["SCOPEID"] = scopeID.ToString();
320 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
321 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
322 sendData["METHOD"] = "getagents";
323
324 sendData["uuids"] = new List<string>(userIDs);
325
326 string reply = string.Empty;
327 string reqString = ServerUtils.BuildQueryString(sendData);
328 //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
329 try
330 {
331 reply = SynchronousRestFormsRequester.MakeRequest("POST",
332 m_ServerURI + "/presence",
333 reqString);
334 if (reply == null || (reply != null && reply == string.Empty))
335 {
336 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply");
337 return null;
338 }
339 }
340 catch (Exception e)
341 {
342 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
343 }
344
345 List<PresenceInfo> rinfos = new List<PresenceInfo>();
346
347 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
348
349 if (replyData != null)
350 {
351 if (replyData.ContainsKey("result") &&
352 (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure"))
353 {
354 return new PresenceInfo[0];
355 }
356
357 Dictionary<string, object>.ValueCollection pinfosList = replyData.Values;
358 //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
359 foreach (object presence in pinfosList)
360 {
361 if (presence is Dictionary<string, object>)
362 {
363 PresenceInfo pinfo = new PresenceInfo((Dictionary<string, object>)presence);
364 rinfos.Add(pinfo);
365 }
366 else
367 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}",
368 presence.GetType());
369 }
370 }
371 else
372 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response");
373
374 return rinfos.ToArray();
375 }
376
377
378 #endregion
379
380 }
381}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
new file mode 100644
index 0000000..3fdee9c
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
@@ -0,0 +1,438 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Connects to the SimianGrid asset service
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class SimianAssetServiceConnector : IAssetService, ISharedRegionModule
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(
53 MethodBase.GetCurrentMethod().DeclaringType);
54 private static string ZeroID = UUID.Zero.ToString();
55
56 private string m_serverUrl = String.Empty;
57 private IImprovedAssetCache m_cache;
58
59 #region ISharedRegionModule
60
61 public Type ReplaceableInterface { get { return null; } }
62 public void RegionLoaded(Scene scene)
63 {
64 if (m_cache == null)
65 {
66 IImprovedAssetCache cache = scene.RequestModuleInterface<IImprovedAssetCache>();
67 if (cache is ISharedRegionModule)
68 m_cache = cache;
69 }
70 }
71 public void PostInitialise() { }
72 public void Close() { }
73
74 public SimianAssetServiceConnector() { }
75 public string Name { get { return "SimianAssetServiceConnector"; } }
76 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAssetService>(this); } }
77 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAssetService>(this); } }
78
79 #endregion ISharedRegionModule
80
81 public SimianAssetServiceConnector(IConfigSource source)
82 {
83 Initialise(source);
84 }
85
86 public void Initialise(IConfigSource source)
87 {
88 if (Simian.IsSimianEnabled(source, "AssetServices", this.Name))
89 {
90 IConfig gridConfig = source.Configs["AssetService"];
91 if (gridConfig == null)
92 {
93 m_log.Error("[SIMIAN ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
94 throw new Exception("Asset connector init error");
95 }
96
97 string serviceUrl = gridConfig.GetString("AssetServerURI");
98 if (String.IsNullOrEmpty(serviceUrl))
99 {
100 m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI in section AssetService");
101 throw new Exception("Asset connector init error");
102 }
103
104 if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
105 serviceUrl = serviceUrl + '/';
106
107 m_serverUrl = serviceUrl;
108 }
109 }
110
111 #region IAssetService
112
113 public AssetBase Get(string id)
114 {
115 // Cache fetch
116 if (m_cache != null)
117 {
118 AssetBase asset = m_cache.Get(id);
119 if (asset != null)
120 return asset;
121 }
122
123 return GetRemote(id);
124 }
125
126 public AssetBase GetCached(string id)
127 {
128 if (m_cache != null)
129 return m_cache.Get(id);
130
131 return null;
132 }
133
134 /// <summary>
135 /// Get an asset's metadata
136 /// </summary>
137 /// <param name="id"></param>
138 /// <returns></returns>
139 public AssetMetadata GetMetadata(string id)
140 {
141 AssetMetadata metadata = null;
142
143 // Cache fetch
144 if (m_cache != null)
145 {
146 AssetBase asset = m_cache.Get(id);
147 if (asset != null)
148 return asset.Metadata;
149 }
150
151 Uri url;
152
153 // Determine if id is an absolute URL or a grid-relative UUID
154 if (!Uri.TryCreate(id, UriKind.Absolute, out url))
155 url = new Uri(m_serverUrl + id);
156
157 try
158 {
159 HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
160 request.Method = "HEAD";
161
162 using (WebResponse response = request.GetResponse())
163 {
164 using (Stream responseStream = response.GetResponseStream())
165 {
166 // Create the metadata object
167 metadata = new AssetMetadata();
168 metadata.ContentType = response.ContentType;
169 metadata.ID = id;
170
171 UUID uuid;
172 if (UUID.TryParse(id, out uuid))
173 metadata.FullID = uuid;
174
175 string lastModifiedStr = response.Headers.Get("Last-Modified");
176 if (!String.IsNullOrEmpty(lastModifiedStr))
177 {
178 DateTime lastModified;
179 if (DateTime.TryParse(lastModifiedStr, out lastModified))
180 metadata.CreationDate = lastModified;
181 }
182 }
183 }
184 }
185 catch (Exception ex)
186 {
187 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
188 }
189
190 return metadata;
191 }
192
193 public byte[] GetData(string id)
194 {
195 AssetBase asset = Get(id);
196
197 if (asset != null)
198 return asset.Data;
199
200 return null;
201 }
202
203 /// <summary>
204 /// Get an asset asynchronously
205 /// </summary>
206 /// <param name="id">The asset id</param>
207 /// <param name="sender">Represents the requester. Passed back via the handler</param>
208 /// <param name="handler">The handler to call back once the asset has been retrieved</param>
209 /// <returns>True if the id was parseable, false otherwise</returns>
210 public bool Get(string id, Object sender, AssetRetrieved handler)
211 {
212 // Cache fetch
213 if (m_cache != null)
214 {
215 AssetBase asset = m_cache.Get(id);
216 if (asset != null)
217 {
218 handler(id, sender, asset);
219 return true;
220 }
221 }
222
223 Util.FireAndForget(
224 delegate(object o)
225 {
226 AssetBase asset = GetRemote(id);
227 handler(id, sender, asset);
228 }
229 );
230
231 return true;
232 }
233
234 /// <summary>
235 /// Creates a new asset
236 /// </summary>
237 /// Returns a random ID if none is passed into it
238 /// <param name="asset"></param>
239 /// <returns></returns>
240 public string Store(AssetBase asset)
241 {
242 bool storedInCache = false;
243 string errorMessage = null;
244
245 // AssetID handling
246 if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID)
247 {
248 asset.FullID = UUID.Random();
249 asset.ID = asset.FullID.ToString();
250 }
251
252 // Cache handling
253 if (m_cache != null)
254 {
255 m_cache.Cache(asset);
256 storedInCache = true;
257 }
258
259 // Local asset handling
260 if (asset.Local)
261 {
262 if (!storedInCache)
263 {
264 m_log.Error("Cannot store local " + asset.Metadata.ContentType + " asset without an asset cache");
265 asset.ID = null;
266 asset.FullID = UUID.Zero;
267 }
268
269 return asset.ID;
270 }
271
272 // Distinguish public and private assets
273 bool isPublic = true;
274 switch ((AssetType)asset.Type)
275 {
276 case AssetType.CallingCard:
277 case AssetType.Gesture:
278 case AssetType.LSLBytecode:
279 case AssetType.LSLText:
280 isPublic = false;
281 break;
282 }
283
284 // Make sure ContentType is set
285 if (String.IsNullOrEmpty(asset.Metadata.ContentType))
286 asset.Metadata.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type);
287
288 // Build the remote storage request
289 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
290 {
291 new MultipartForm.Parameter("AssetID", asset.FullID.ToString()),
292 new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID),
293 new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"),
294 new MultipartForm.Parameter("Public", isPublic ? "1" : "0"),
295 new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data)
296 };
297
298 // Make the remote storage request
299 try
300 {
301 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
302
303 HttpWebResponse response = MultipartForm.Post(request, postParameters);
304 using (Stream responseStream = response.GetResponseStream())
305 {
306 string responseStr = null;
307
308 try
309 {
310 responseStr = responseStream.GetStreamString();
311 OSD responseOSD = OSDParser.Deserialize(responseStr);
312 if (responseOSD.Type == OSDType.Map)
313 {
314 OSDMap responseMap = (OSDMap)responseOSD;
315 if (responseMap["Success"].AsBoolean())
316 return asset.ID;
317 else
318 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
319 }
320 else
321 {
322 errorMessage = "Response format was invalid:\n" + responseStr;
323 }
324 }
325 catch (Exception ex)
326 {
327 if (!String.IsNullOrEmpty(responseStr))
328 errorMessage = "Failed to parse the response:\n" + responseStr;
329 else
330 errorMessage = "Failed to retrieve the response: " + ex.Message;
331 }
332 }
333 }
334 catch (WebException ex)
335 {
336 errorMessage = ex.Message;
337 }
338
339 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}",
340 asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage);
341 return null;
342 }
343
344 /// <summary>
345 /// Update an asset's content
346 /// </summary>
347 /// Attachments and bare scripts need this!!
348 /// <param name="id"> </param>
349 /// <param name="data"></param>
350 /// <returns></returns>
351 public bool UpdateContent(string id, byte[] data)
352 {
353 AssetBase asset = Get(id);
354
355 if (asset == null)
356 {
357 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Failed to fetch asset " + id + " for updating");
358 return false;
359 }
360
361 asset.Data = data;
362
363 string result = Store(asset);
364 return !String.IsNullOrEmpty(result);
365 }
366
367 /// <summary>
368 /// Delete an asset
369 /// </summary>
370 /// <param name="id"></param>
371 /// <returns></returns>
372 public bool Delete(string id)
373 {
374 if (m_cache != null)
375 m_cache.Expire(id);
376
377 string url = m_serverUrl + id;
378
379 OSDMap response = WebUtil.ServiceRequest(url, "DELETE");
380 if (response["Success"].AsBoolean())
381 return true;
382 else
383 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service");
384
385 return false;
386 }
387
388 #endregion IAssetService
389
390 private AssetBase GetRemote(string id)
391 {
392 AssetBase asset = null;
393 Uri url;
394
395 // Determine if id is an absolute URL or a grid-relative UUID
396 if (!Uri.TryCreate(id, UriKind.Absolute, out url))
397 url = new Uri(m_serverUrl + id);
398
399 try
400 {
401 HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
402
403 using (WebResponse response = request.GetResponse())
404 {
405 using (Stream responseStream = response.GetResponseStream())
406 {
407 string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty;
408
409 // Create the asset object
410 asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID);
411
412 UUID assetID;
413 if (UUID.TryParse(id, out assetID))
414 asset.FullID = assetID;
415
416 // Grab the asset data from the response stream
417 using (MemoryStream stream = new MemoryStream())
418 {
419 responseStream.CopyTo(stream, Int32.MaxValue);
420 asset.Data = stream.ToArray();
421 }
422 }
423 }
424
425 // Cache store
426 if (m_cache != null && asset != null)
427 m_cache.Cache(asset);
428
429 return asset;
430 }
431 catch (Exception ex)
432 {
433 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
434 return null;
435 }
436 }
437 }
438}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
new file mode 100644
index 0000000..b19135e
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
@@ -0,0 +1,246 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Specialized;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40
41namespace OpenSim.Services.Connectors.SimianGrid
42{
43 /// <summary>
44 /// Connects authentication/authorization to the SimianGrid backend
45 /// </summary>
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47 public class SimianAuthenticationServiceConnector : IAuthenticationService, ISharedRegionModule
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType);
52
53 private string m_serverUrl = String.Empty;
54
55 #region ISharedRegionModule
56
57 public Type ReplaceableInterface { get { return null; } }
58 public void RegionLoaded(Scene scene) { }
59 public void PostInitialise() { }
60 public void Close() { }
61
62 public SimianAuthenticationServiceConnector() { }
63 public string Name { get { return "SimianAuthenticationServiceConnector"; } }
64 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAuthenticationService>(this); } }
65 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAuthenticationService>(this); } }
66
67 #endregion ISharedRegionModule
68
69 public SimianAuthenticationServiceConnector(IConfigSource source)
70 {
71 Initialise(source);
72 }
73
74 public void Initialise(IConfigSource source)
75 {
76 if (Simian.IsSimianEnabled(source, "AuthenticationServices", this.Name))
77 {
78 IConfig assetConfig = source.Configs["AuthenticationService"];
79 if (assetConfig == null)
80 {
81 m_log.Error("[SIMIAN AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini");
82 throw new Exception("Authentication connector init error");
83 }
84
85 string serviceURI = assetConfig.GetString("AuthenticationServerURI");
86 if (String.IsNullOrEmpty(serviceURI))
87 {
88 m_log.Error("[SIMIAN AUTH CONNECTOR]: No Server URI named in section AuthenticationService");
89 throw new Exception("Authentication connector init error");
90 }
91
92 m_serverUrl = serviceURI;
93 }
94 }
95
96 public string Authenticate(UUID principalID, string password, int lifetime)
97 {
98 NameValueCollection requestArgs = new NameValueCollection
99 {
100 { "RequestMethod", "GetIdentities" },
101 { "UserID", principalID.ToString() }
102 };
103
104 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
105 if (response["Success"].AsBoolean() && response["Identities"] is OSDArray)
106 {
107 bool md5hashFound = false;
108
109 OSDArray identities = (OSDArray)response["Identities"];
110 for (int i = 0; i < identities.Count; i++)
111 {
112 OSDMap identity = identities[i] as OSDMap;
113 if (identity != null)
114 {
115 if (identity["Type"].AsString() == "md5hash")
116 {
117 string credential = identity["Credential"].AsString();
118
119 if (password == credential || "$1$" + Utils.MD5String(password) == credential || Utils.MD5String(password) == credential)
120 return Authorize(principalID);
121
122 md5hashFound = true;
123 break;
124 }
125 }
126 }
127
128 if (md5hashFound)
129 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Authentication failed for " + principalID + " using md5hash $1$" + Utils.MD5String(password));
130 else
131 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Authentication failed for " + principalID + ", no md5hash identity found");
132 }
133 else
134 {
135 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " +
136 response["Message"].AsString());
137 }
138
139 return String.Empty;
140 }
141
142 public bool Verify(UUID principalID, string token, int lifetime)
143 {
144 NameValueCollection requestArgs = new NameValueCollection
145 {
146 { "RequestMethod", "GetSession" },
147 { "SessionID", token }
148 };
149
150 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
151 if (response["Success"].AsBoolean())
152 {
153 return true;
154 }
155 else
156 {
157 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Could not verify session for " + principalID + ": " +
158 response["Message"].AsString());
159 }
160
161 return false;
162 }
163
164 public bool Release(UUID principalID, string token)
165 {
166 NameValueCollection requestArgs = new NameValueCollection
167 {
168 { "RequestMethod", "RemoveSession" },
169 { "UserID", principalID.ToString() }
170 };
171
172 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
173 if (response["Success"].AsBoolean())
174 {
175 return true;
176 }
177 else
178 {
179 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Failed to remove session for " + principalID + ": " +
180 response["Message"].AsString());
181 }
182
183 return false;
184 }
185
186 public bool SetPassword(UUID principalID, string passwd)
187 {
188 // Fetch the user name first
189 NameValueCollection requestArgs = new NameValueCollection
190 {
191 { "RequestMethod", "GetUser" },
192 { "UserID", principalID.ToString() }
193 };
194
195 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
196 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
197 {
198 OSDMap userMap = (OSDMap)response["User"];
199 string identifier = userMap["Name"].AsString();
200
201 if (!String.IsNullOrEmpty(identifier))
202 {
203 // Add/update the md5hash identity
204 requestArgs = new NameValueCollection
205 {
206 { "RequestMethod", "AddIdentity" },
207 { "Identifier", identifier },
208 { "Credential", "$1$" + Utils.MD5String(passwd) },
209 { "Type", "md5hash" },
210 { "UserID", principalID.ToString() }
211 };
212
213 response = WebUtil.PostToService(m_serverUrl, requestArgs);
214 bool success = response["Success"].AsBoolean();
215
216 if (!success)
217 m_log.WarnFormat("[SIMIAN AUTH CONNECTOR]: Failed to set password for {0} ({1})", identifier, principalID);
218
219 return success;
220 }
221 }
222 else
223 {
224 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " +
225 response["Message"].AsString());
226 }
227
228 return false;
229 }
230
231 private string Authorize(UUID userID)
232 {
233 NameValueCollection requestArgs = new NameValueCollection
234 {
235 { "RequestMethod", "AddSession" },
236 { "UserID", userID.ToString() }
237 };
238
239 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
240 if (response["Success"].AsBoolean())
241 return response["SessionID"].AsUUID().ToString();
242 else
243 return String.Empty;
244 }
245 }
246}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
new file mode 100644
index 0000000..a47f32c
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
@@ -0,0 +1,262 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using log4net;
35using Mono.Addins;
36using Nini.Config;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Server.Base;
41using OpenSim.Services.Interfaces;
42using OpenMetaverse;
43using OpenMetaverse.StructuredData;
44
45namespace OpenSim.Services.Connectors.SimianGrid
46{
47 /// <summary>
48 /// Connects avatar appearance data to the SimianGrid backend
49 /// </summary>
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56 private static string ZeroID = UUID.Zero.ToString();
57
58 private string m_serverUrl = String.Empty;
59
60 #region ISharedRegionModule
61
62 public Type ReplaceableInterface { get { return null; } }
63 public void RegionLoaded(Scene scene) { }
64 public void PostInitialise() { }
65 public void Close() { }
66
67 public SimianAvatarServiceConnector() { }
68 public string Name { get { return "SimianAvatarServiceConnector"; } }
69 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAvatarService>(this); } }
70 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAvatarService>(this); } }
71
72 #endregion ISharedRegionModule
73
74 public SimianAvatarServiceConnector(IConfigSource source)
75 {
76 Initialise(source);
77 }
78
79 public void Initialise(IConfigSource source)
80 {
81 if (Simian.IsSimianEnabled(source, "AvatarServices", this.Name))
82 {
83 IConfig gridConfig = source.Configs["AvatarService"];
84 if (gridConfig == null)
85 {
86 m_log.Error("[SIMIAN AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini");
87 throw new Exception("Avatar connector init error");
88 }
89
90 string serviceUrl = gridConfig.GetString("AvatarServerURI");
91 if (String.IsNullOrEmpty(serviceUrl))
92 {
93 m_log.Error("[SIMIAN AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService");
94 throw new Exception("Avatar connector init error");
95 }
96
97 if (!serviceUrl.EndsWith("/"))
98 serviceUrl = serviceUrl + '/';
99
100 m_serverUrl = serviceUrl;
101 }
102 }
103
104 #region IAvatarService
105
106 public AvatarData GetAvatar(UUID userID)
107 {
108 NameValueCollection requestArgs = new NameValueCollection
109 {
110 { "RequestMethod", "GetUser" },
111 { "UserID", userID.ToString() }
112 };
113
114 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
115 if (response["Success"].AsBoolean())
116 {
117 OSDMap map = null;
118 try { map = OSDParser.DeserializeJson(response["LLAppearance"].AsString()) as OSDMap; }
119 catch { }
120
121 if (map != null)
122 {
123 AvatarWearable[] wearables = new AvatarWearable[13];
124 wearables[0] = new AvatarWearable(map["ShapeItem"].AsUUID(), map["ShapeAsset"].AsUUID());
125 wearables[1] = new AvatarWearable(map["SkinItem"].AsUUID(), map["SkinAsset"].AsUUID());
126 wearables[2] = new AvatarWearable(map["HairItem"].AsUUID(), map["HairAsset"].AsUUID());
127 wearables[3] = new AvatarWearable(map["EyesItem"].AsUUID(), map["EyesAsset"].AsUUID());
128 wearables[4] = new AvatarWearable(map["ShirtItem"].AsUUID(), map["ShirtAsset"].AsUUID());
129 wearables[5] = new AvatarWearable(map["PantsItem"].AsUUID(), map["PantsAsset"].AsUUID());
130 wearables[6] = new AvatarWearable(map["ShoesItem"].AsUUID(), map["ShoesAsset"].AsUUID());
131 wearables[7] = new AvatarWearable(map["SocksItem"].AsUUID(), map["SocksAsset"].AsUUID());
132 wearables[8] = new AvatarWearable(map["JacketItem"].AsUUID(), map["JacketAsset"].AsUUID());
133 wearables[9] = new AvatarWearable(map["GlovesItem"].AsUUID(), map["GlovesAsset"].AsUUID());
134 wearables[10] = new AvatarWearable(map["UndershirtItem"].AsUUID(), map["UndershirtAsset"].AsUUID());
135 wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID());
136 wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID());
137
138 AvatarAppearance appearance = new AvatarAppearance(userID);
139 appearance.Wearables = wearables;
140 appearance.AvatarHeight = (float)map["Height"].AsReal();
141
142 AvatarData avatar = new AvatarData(appearance);
143
144 // Get attachments
145 map = null;
146 try { map = OSDParser.DeserializeJson(response["LLAttachments"].AsString()) as OSDMap; }
147 catch { }
148
149 if (map != null)
150 {
151 foreach (KeyValuePair<string, OSD> kvp in map)
152 avatar.Data[kvp.Key] = kvp.Value.AsString();
153 }
154
155 return avatar;
156 }
157 else
158 {
159 m_log.Warn("[SIMIAN AVATAR CONNECTOR]: Failed to get user appearance for " + userID +
160 ", LLAppearance is missing or invalid");
161 return null;
162 }
163 }
164 else
165 {
166 m_log.Warn("[SIMIAN AVATAR CONNECTOR]: Failed to get user appearance for " + userID + ": " +
167 response["Message"].AsString());
168 }
169
170 return null;
171 }
172
173 public bool SetAvatar(UUID userID, AvatarData avatar)
174 {
175 m_log.Debug("[SIMIAN AVATAR CONNECTOR]: SetAvatar called for " + userID);
176
177 if (avatar.AvatarType == 1) // LLAvatar
178 {
179 AvatarAppearance appearance = avatar.ToAvatarAppearance(userID);
180
181 OSDMap map = new OSDMap();
182
183 map["Height"] = OSD.FromReal(appearance.AvatarHeight);
184
185 map["ShapeItem"] = OSD.FromUUID(appearance.BodyItem);
186 map["ShapeAsset"] = OSD.FromUUID(appearance.BodyAsset);
187 map["SkinItem"] = OSD.FromUUID(appearance.SkinItem);
188 map["SkinAsset"] = OSD.FromUUID(appearance.SkinAsset);
189 map["HairItem"] = OSD.FromUUID(appearance.HairItem);
190 map["HairAsset"] = OSD.FromUUID(appearance.HairAsset);
191 map["EyesItem"] = OSD.FromUUID(appearance.EyesItem);
192 map["EyesAsset"] = OSD.FromUUID(appearance.EyesAsset);
193 map["ShirtItem"] = OSD.FromUUID(appearance.ShirtItem);
194 map["ShirtAsset"] = OSD.FromUUID(appearance.ShirtAsset);
195 map["PantsItem"] = OSD.FromUUID(appearance.PantsItem);
196 map["PantsAsset"] = OSD.FromUUID(appearance.PantsAsset);
197 map["ShoesItem"] = OSD.FromUUID(appearance.ShoesItem);
198 map["ShoesAsset"] = OSD.FromUUID(appearance.ShoesAsset);
199 map["SocksItem"] = OSD.FromUUID(appearance.SocksItem);
200 map["SocksAsset"] = OSD.FromUUID(appearance.SocksAsset);
201 map["JacketItem"] = OSD.FromUUID(appearance.JacketItem);
202 map["JacketAsset"] = OSD.FromUUID(appearance.JacketAsset);
203 map["GlovesItem"] = OSD.FromUUID(appearance.GlovesItem);
204 map["GlovesAsset"] = OSD.FromUUID(appearance.GlovesAsset);
205 map["UndershirtItem"] = OSD.FromUUID(appearance.UnderShirtItem);
206 map["UndershirtAsset"] = OSD.FromUUID(appearance.UnderShirtAsset);
207 map["UnderpantsItem"] = OSD.FromUUID(appearance.UnderPantsItem);
208 map["UnderpantsAsset"] = OSD.FromUUID(appearance.UnderPantsAsset);
209 map["SkirtItem"] = OSD.FromUUID(appearance.SkirtItem);
210 map["SkirtAsset"] = OSD.FromUUID(appearance.SkirtAsset);
211
212 OSDMap items = new OSDMap();
213 foreach (KeyValuePair<string, string> kvp in avatar.Data)
214 {
215 if (kvp.Key.StartsWith("_ap_"))
216 items.Add(kvp.Key, OSD.FromString(kvp.Value));
217 }
218
219 NameValueCollection requestArgs = new NameValueCollection
220 {
221 { "RequestMethod", "AddUserData" },
222 { "UserID", userID.ToString() },
223 { "LLAppearance", OSDParser.SerializeJsonString(map) },
224 { "LLAttachments", OSDParser.SerializeJsonString(items) }
225 };
226
227 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
228 bool success = response["Success"].AsBoolean();
229
230 if (!success)
231 m_log.Warn("[SIMIAN AVATAR CONNECTOR]: Failed saving appearance for " + userID + ": " + response["Message"].AsString());
232
233 return success;
234 }
235 else
236 {
237 m_log.Error("[SIMIAN AVATAR CONNECTOR]: Can't save appearance for " + userID + ". Unhandled avatar type " + avatar.AvatarType);
238 return false;
239 }
240 }
241
242 public bool ResetAvatar(UUID userID)
243 {
244 m_log.Error("[SIMIAN AVATAR CONNECTOR]: ResetAvatar called for " + userID + ", implement this");
245 return false;
246 }
247
248 public bool SetItems(UUID userID, string[] names, string[] values)
249 {
250 m_log.Error("[SIMIAN AVATAR CONNECTOR]: SetItems called for " + userID + " with " + names.Length + " names and " + values.Length + " values, implement this");
251 return false;
252 }
253
254 public bool RemoveItems(UUID userID, string[] names)
255 {
256 m_log.Error("[SIMIAN AVATAR CONNECTOR]: RemoveItems called for " + userID + " with " + names.Length + " names, implement this");
257 return false;
258 }
259
260 #endregion IAvatarService
261 }
262}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
new file mode 100644
index 0000000..89f3594
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -0,0 +1,240 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.Reflection;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43
44namespace OpenSim.Services.Connectors.SimianGrid
45{
46 /// <summary>
47 /// Stores and retrieves friend lists from the SimianGrid backend
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class SimianFriendsServiceConnector : IFriendsService, ISharedRegionModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private string m_serverUrl = String.Empty;
57
58 #region ISharedRegionModule
59
60 public Type ReplaceableInterface { get { return null; } }
61 public void RegionLoaded(Scene scene) { }
62 public void PostInitialise() { }
63 public void Close() { }
64
65 public SimianFriendsServiceConnector() { }
66 public string Name { get { return "SimianFriendsServiceConnector"; } }
67 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IFriendsService>(this); } }
68 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IFriendsService>(this); } }
69
70 #endregion ISharedRegionModule
71
72 public SimianFriendsServiceConnector(IConfigSource source)
73 {
74 Initialise(source);
75 }
76
77 public void Initialise(IConfigSource source)
78 {
79 bool isSimianEnabled = false;
80
81 if (source.Configs["Friends"] != null)
82 {
83 string module = source.Configs["Friends"].GetString("Connector");
84 isSimianEnabled = !String.IsNullOrEmpty(module) && module.EndsWith(this.Name);
85 }
86
87 if (isSimianEnabled)
88 {
89 IConfig assetConfig = source.Configs["FriendsService"];
90 if (assetConfig == null)
91 {
92 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini");
93 throw new Exception("Friends connector init error");
94 }
95
96 string serviceURI = assetConfig.GetString("FriendsServerURI");
97 if (String.IsNullOrEmpty(serviceURI))
98 {
99 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: No Server URI named in section FriendsService");
100 throw new Exception("Friends connector init error");
101 }
102
103 m_serverUrl = serviceURI;
104 }
105 }
106
107 #region IFriendsService
108
109 public FriendInfo[] GetFriends(UUID principalID)
110 {
111 Dictionary<UUID, FriendInfo> friends = new Dictionary<UUID, FriendInfo>();
112
113 OSDArray friendsArray = GetFriended(principalID);
114 OSDArray friendedMeArray = GetFriendedBy(principalID);
115
116 // Load the list of friends and their granted permissions
117 for (int i = 0; i < friendsArray.Count; i++)
118 {
119 OSDMap friendEntry = friendsArray[i] as OSDMap;
120 if (friendEntry != null)
121 {
122 UUID friendID = friendEntry["Key"].AsUUID();
123
124 FriendInfo friend = new FriendInfo();
125 friend.PrincipalID = principalID;
126 friend.Friend = friendID.ToString();
127 friend.MyFlags = friendEntry["Value"].AsInteger();
128 friend.TheirFlags = -1;
129
130 friends[friendID] = friend;
131 }
132 }
133
134 // Load the permissions those friends have granted to this user
135 for (int i = 0; i < friendedMeArray.Count; i++)
136 {
137 OSDMap friendedMeEntry = friendedMeArray[i] as OSDMap;
138 if (friendedMeEntry != null)
139 {
140 UUID friendID = friendedMeEntry["OwnerID"].AsUUID();
141
142 FriendInfo friend;
143 if (friends.TryGetValue(friendID, out friend))
144 friend.TheirFlags = friendedMeEntry["Value"].AsInteger();
145 }
146 }
147
148 // Convert the dictionary of friends to an array and return it
149 FriendInfo[] array = new FriendInfo[friends.Count];
150 int j = 0;
151 foreach (FriendInfo friend in friends.Values)
152 array[j++] = friend;
153
154 return array;
155 }
156
157 public bool StoreFriend(UUID principalID, string friend, int flags)
158 {
159 NameValueCollection requestArgs = new NameValueCollection
160 {
161 { "RequestMethod", "AddGeneric" },
162 { "OwnerID", principalID.ToString() },
163 { "Type", "Friend" },
164 { "Key", friend },
165 { "Value", flags.ToString() }
166 };
167
168 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
169 bool success = response["Success"].AsBoolean();
170
171 if (!success)
172 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: Failed to store friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
173
174 return success;
175 }
176
177 public bool Delete(UUID principalID, string friend)
178 {
179 NameValueCollection requestArgs = new NameValueCollection
180 {
181 { "RequestMethod", "RemoveGeneric" },
182 { "OwnerID", principalID.ToString() },
183 { "Type", "Friend" },
184 { "Key", friend }
185 };
186
187 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
188 bool success = response["Success"].AsBoolean();
189
190 if (!success)
191 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: Failed to remove friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
192
193 return success;
194 }
195
196 #endregion IFriendsService
197
198 private OSDArray GetFriended(UUID ownerID)
199 {
200 NameValueCollection requestArgs = new NameValueCollection
201 {
202 { "RequestMethod", "GetGenerics" },
203 { "OwnerID", ownerID.ToString() },
204 { "Type", "Friend" }
205 };
206
207 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
208 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
209 {
210 return (OSDArray)response["Entries"];
211 }
212 else
213 {
214 m_log.Warn("[SIMIAN FRIENDS CONNECTOR]: Failed to retrieve friends for user " + ownerID + ": " + response["Message"].AsString());
215 return new OSDArray(0);
216 }
217 }
218
219 private OSDArray GetFriendedBy(UUID ownerID)
220 {
221 NameValueCollection requestArgs = new NameValueCollection
222 {
223 { "RequestMethod", "GetGenerics" },
224 { "Key", ownerID.ToString() },
225 { "Type", "Friend" }
226 };
227
228 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
229 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
230 {
231 return (OSDArray)response["Entries"];
232 }
233 else
234 {
235 m_log.Warn("[SIMIAN FRIENDS CONNECTOR]: Failed to retrieve reverse friends for user " + ownerID + ": " + response["Message"].AsString());
236 return new OSDArray(0);
237 }
238 }
239 }
240}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
new file mode 100644
index 0000000..7d97aaa
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Mono.Addins;
30using Nini.Config;
31
32[assembly: Addin("SimianGrid", "1.0")]
33[assembly: AddinDependency("OpenSim", "0.5")]
34
35public static class Simian
36{
37 public static bool IsSimianEnabled(IConfigSource config, string moduleName, string connectorName)
38 {
39 if (config.Configs["Modules"] != null)
40 {
41 string module = config.Configs["Modules"].GetString(moduleName);
42 return !String.IsNullOrEmpty(module) && module.EndsWith(connectorName);
43 }
44
45 return false;
46 }
47} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
new file mode 100644
index 0000000..3a61226
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.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
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.Net;
32using System.Reflection;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Server.Base;
42using OpenMetaverse;
43using OpenMetaverse.StructuredData;
44
45using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46
47namespace OpenSim.Services.Connectors.SimianGrid
48{
49 /// <summary>
50 /// Connects region registration and neighbor lookups to the SimianGrid
51 /// backend
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
54 public class SimianGridServiceConnector : IGridService, ISharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(
58 MethodBase.GetCurrentMethod().DeclaringType);
59
60 private string m_serverUrl = String.Empty;
61
62 #region ISharedRegionModule
63
64 public Type ReplaceableInterface { get { return null; } }
65 public void RegionLoaded(Scene scene) { }
66 public void PostInitialise() { }
67 public void Close() { }
68
69 public SimianGridServiceConnector() { }
70 public string Name { get { return "SimianGridServiceConnector"; } }
71 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IGridService>(this); } }
72 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IGridService>(this); } }
73
74 #endregion ISharedRegionModule
75
76 public SimianGridServiceConnector(IConfigSource source)
77 {
78 Initialise(source);
79 }
80
81 public void Initialise(IConfigSource source)
82 {
83 if (Simian.IsSimianEnabled(source, "GridServices", this.Name))
84 {
85 IConfig gridConfig = source.Configs["GridService"];
86 if (gridConfig == null)
87 {
88 m_log.Error("[SIMIAN GRID CONNECTOR]: GridService missing from OpenSim.ini");
89 throw new Exception("Grid connector init error");
90 }
91
92 string serviceUrl = gridConfig.GetString("GridServerURI");
93 if (String.IsNullOrEmpty(serviceUrl))
94 {
95 m_log.Error("[SIMIAN GRID CONNECTOR]: No Server URI named in section GridService");
96 throw new Exception("Grid connector init error");
97 }
98
99 m_serverUrl = serviceUrl;
100 }
101 }
102
103 #region IGridService
104
105 public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
106 {
107 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
108 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0);
109
110 string httpAddress = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "/";
111
112 OSDMap extraData = new OSDMap
113 {
114 { "ServerURI", OSD.FromString(regionInfo.ServerURI) },
115 { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) },
116 { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) },
117 { "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) },
118 { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) },
119 { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) },
120 { "Access", OSD.FromInteger(regionInfo.Access) },
121 { "RegionSecret", OSD.FromString(regionInfo.RegionSecret) },
122 { "EstateOwner", OSD.FromUUID(regionInfo.EstateOwner) },
123 { "Token", OSD.FromString(regionInfo.Token) }
124 };
125
126 NameValueCollection requestArgs = new NameValueCollection
127 {
128 { "RequestMethod", "AddScene" },
129 { "SceneID", regionInfo.RegionID.ToString() },
130 { "Name", regionInfo.RegionName },
131 { "MinPosition", minPosition.ToString() },
132 { "MaxPosition", maxPosition.ToString() },
133 { "Address", httpAddress },
134 { "Enabled", "1" },
135 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
136 };
137
138 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
139 if (response["Success"].AsBoolean())
140 return String.Empty;
141 else
142 return "Region registration for " + regionInfo.RegionName + " failed: " + response["Message"].AsString();
143 }
144
145 public bool DeregisterRegion(UUID regionID)
146 {
147 NameValueCollection requestArgs = new NameValueCollection
148 {
149 { "RequestMethod", "AddScene" },
150 { "SceneID", regionID.ToString() },
151 { "Enabled", "0" }
152 };
153
154 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
155 bool success = response["Success"].AsBoolean();
156
157 if (!success)
158 m_log.Warn("[SIMIAN GRID CONNECTOR]: Region deregistration for " + regionID + " failed: " + response["Message"].AsString());
159
160 return success;
161 }
162
163 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
164 {
165 const int NEIGHBOR_RADIUS = 128;
166
167 GridRegion region = GetRegionByUUID(scopeID, regionID);
168
169 if (region != null)
170 {
171 List<GridRegion> regions = GetRegionRange(scopeID,
172 region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + (int)Constants.RegionSize + NEIGHBOR_RADIUS,
173 region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + (int)Constants.RegionSize + NEIGHBOR_RADIUS);
174
175 for (int i = 0; i < regions.Count; i++)
176 {
177 if (regions[i].RegionID == regionID)
178 {
179 regions.RemoveAt(i);
180 break;
181 }
182 }
183
184 m_log.Debug("[SIMIAN GRID CONNECTOR]: Found " + regions.Count + " neighbors for region " + regionID);
185 return regions;
186 }
187
188 return new List<GridRegion>(0);
189 }
190
191 public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
192 {
193 NameValueCollection requestArgs = new NameValueCollection
194 {
195 { "RequestMethod", "GetScene" },
196 { "SceneID", regionID.ToString() }
197 };
198
199 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
200 if (response["Success"].AsBoolean())
201 {
202 return ResponseToGridRegion(response);
203 }
204 else
205 {
206 m_log.Warn("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region " + regionID);
207 return null;
208 }
209 }
210
211 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
212 {
213 // Go one meter in from the requested x/y coords to avoid requesting a position
214 // that falls on the border of two sims
215 Vector3d position = new Vector3d(x + 1, y + 1, 0.0);
216
217 NameValueCollection requestArgs = new NameValueCollection
218 {
219 { "RequestMethod", "GetScene" },
220 { "Position", position.ToString() },
221 { "Enabled", "1" }
222 };
223
224 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
225 if (response["Success"].AsBoolean())
226 {
227 return ResponseToGridRegion(response);
228 }
229 else
230 {
231 //m_log.InfoFormat("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}",
232 // x / Constants.RegionSize, y / Constants.RegionSize);
233 return null;
234 }
235 }
236
237 public GridRegion GetRegionByName(UUID scopeID, string regionName)
238 {
239 List<GridRegion> regions = GetRegionsByName(scopeID, regionName, 1);
240
241 m_log.Debug("[SIMIAN GRID CONNECTOR]: Got " + regions.Count + " matches for region name " + regionName);
242
243 if (regions.Count > 0)
244 return regions[0];
245
246 return null;
247 }
248
249 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
250 {
251 List<GridRegion> foundRegions = new List<GridRegion>();
252
253 NameValueCollection requestArgs = new NameValueCollection
254 {
255 { "RequestMethod", "GetScenes" },
256 { "NameQuery", name },
257 { "Enabled", "1" }
258 };
259 if (maxNumber > 0)
260 requestArgs["MaxNumber"] = maxNumber.ToString();
261
262 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
263 if (response["Success"].AsBoolean())
264 {
265 OSDArray array = response["Scenes"] as OSDArray;
266 if (array != null)
267 {
268 for (int i = 0; i < array.Count; i++)
269 {
270 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
271 if (region != null)
272 foundRegions.Add(region);
273 }
274 }
275 }
276
277 return foundRegions;
278 }
279
280 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
281 {
282 List<GridRegion> foundRegions = new List<GridRegion>();
283
284 Vector3d minPosition = new Vector3d(xmin, ymin, 0.0);
285 Vector3d maxPosition = new Vector3d(xmax, ymax, 4096.0);
286
287 NameValueCollection requestArgs = new NameValueCollection
288 {
289 { "RequestMethod", "GetScenes" },
290 { "MinPosition", minPosition.ToString() },
291 { "MaxPosition", maxPosition.ToString() },
292 { "Enabled", "1" }
293 };
294
295 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
296 if (response["Success"].AsBoolean())
297 {
298 OSDArray array = response["Scenes"] as OSDArray;
299 if (array != null)
300 {
301 for (int i = 0; i < array.Count; i++)
302 {
303 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
304 if (region != null)
305 foundRegions.Add(region);
306 }
307 }
308 }
309
310 return foundRegions;
311 }
312
313 public List<GridRegion> GetDefaultRegions(UUID scopeID)
314 {
315 // TODO: Allow specifying the default grid location
316 const int DEFAULT_X = 1000 * 256;
317 const int DEFAULT_Y = 1000 * 256;
318
319 GridRegion defRegion = GetNearestRegion(new Vector3d(DEFAULT_X, DEFAULT_Y, 0.0), true);
320 if (defRegion != null)
321 return new List<GridRegion>(1) { defRegion };
322 else
323 return new List<GridRegion>(0);
324 }
325
326 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
327 {
328 GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
329 if (defRegion != null)
330 return new List<GridRegion>(1) { defRegion };
331 else
332 return new List<GridRegion>(0);
333 }
334
335 public int GetRegionFlags(UUID scopeID, UUID regionID)
336 {
337 const int REGION_ONLINE = 4;
338
339 NameValueCollection requestArgs = new NameValueCollection
340 {
341 { "RequestMethod", "GetScene" },
342 { "SceneID", regionID.ToString() }
343 };
344
345 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
346 if (response["Success"].AsBoolean())
347 {
348 return response["Enabled"].AsBoolean() ? REGION_ONLINE : 0;
349 }
350 else
351 {
352 m_log.Warn("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region " + regionID + " during region flags check");
353 return -1;
354 }
355 }
356
357 #endregion IGridService
358
359 private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled)
360 {
361 NameValueCollection requestArgs = new NameValueCollection
362 {
363 { "RequestMethod", "GetScene" },
364 { "Position", position.ToString() },
365 { "FindClosest", "1" }
366 };
367 if (onlyEnabled)
368 requestArgs["Enabled"] = "1";
369
370 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
371 if (response["Success"].AsBoolean())
372 {
373 return ResponseToGridRegion(response);
374 }
375 else
376 {
377 m_log.Warn("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region at " + position);
378 return null;
379 }
380 }
381
382 private GridRegion ResponseToGridRegion(OSDMap response)
383 {
384 if (response == null)
385 return null;
386
387 OSDMap extraData = response["ExtraData"] as OSDMap;
388 if (extraData == null)
389 return null;
390
391 GridRegion region = new GridRegion();
392
393 region.RegionID = response["SceneID"].AsUUID();
394 region.RegionName = response["Name"].AsString();
395
396 Vector3d minPosition = response["MinPosition"].AsVector3d();
397 region.RegionLocX = (int)minPosition.X;
398 region.RegionLocY = (int)minPosition.Y;
399
400 Uri httpAddress = response["Address"].AsUri();
401 region.ExternalHostName = httpAddress.Host;
402 region.HttpPort = (uint)httpAddress.Port;
403
404 region.ServerURI = extraData["ServerURI"].AsString();
405
406 IPAddress internalAddress;
407 IPAddress.TryParse(extraData["InternalAddress"].AsString(), out internalAddress);
408 if (internalAddress == null)
409 internalAddress = IPAddress.Any;
410
411 region.InternalEndPoint = new IPEndPoint(internalAddress, extraData["InternalPort"].AsInteger());
412 region.TerrainImage = extraData["MapTexture"].AsUUID();
413 region.Access = (byte)extraData["Access"].AsInteger();
414 region.RegionSecret = extraData["RegionSecret"].AsString();
415 region.EstateOwner = extraData["EstateOwner"].AsUUID();
416 region.Token = extraData["Token"].AsString();
417
418 return region;
419 }
420 }
421}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
new file mode 100644
index 0000000..dc68259
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
@@ -0,0 +1,907 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.Reflection;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Server.Base;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Permissions bitflags
47 /// </summary>
48 [Flags]
49 public enum PermissionMask : uint
50 {
51 None = 0,
52 Transfer = 1 << 13,
53 Modify = 1 << 14,
54 Copy = 1 << 15,
55 Move = 1 << 19,
56 Damage = 1 << 20,
57 All = 0x7FFFFFFF
58 }
59
60 /// <summary>
61 /// Connects avatar inventories to the SimianGrid backend
62 /// </summary>
63 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
64 public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule
65 {
66 private static readonly ILog m_log =
67 LogManager.GetLogger(
68 MethodBase.GetCurrentMethod().DeclaringType);
69
70 private string m_serverUrl = String.Empty;
71 private string m_userServerUrl = String.Empty;
72 private object m_gestureSyncRoot = new object();
73
74 #region ISharedRegionModule
75
76 public Type ReplaceableInterface { get { return null; } }
77 public void RegionLoaded(Scene scene) { }
78 public void PostInitialise() { }
79 public void Close() { }
80
81 public SimianInventoryServiceConnector() { }
82 public string Name { get { return "SimianInventoryServiceConnector"; } }
83 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IInventoryService>(this); } }
84 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IInventoryService>(this); } }
85
86 #endregion ISharedRegionModule
87
88 public SimianInventoryServiceConnector(IConfigSource source)
89 {
90 Initialise(source);
91 }
92
93 public void Initialise(IConfigSource source)
94 {
95 if (Simian.IsSimianEnabled(source, "InventoryServices", this.Name))
96 {
97 IConfig gridConfig = source.Configs["InventoryService"];
98 if (gridConfig == null)
99 {
100 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
101 throw new Exception("Inventory connector init error");
102 }
103
104 string serviceUrl = gridConfig.GetString("InventoryServerURI");
105 if (String.IsNullOrEmpty(serviceUrl))
106 {
107 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
108 throw new Exception("Inventory connector init error");
109 }
110
111 m_serverUrl = serviceUrl;
112
113 gridConfig = source.Configs["UserAccountService"];
114 if (gridConfig != null)
115 {
116 serviceUrl = gridConfig.GetString("UserAccountServerURI");
117 if (!String.IsNullOrEmpty(serviceUrl))
118 m_userServerUrl = serviceUrl;
119 else
120 m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No Server URI named in section UserAccountService");
121 }
122 else
123 {
124 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: UserAccountService missing from OpenSim.ini");
125 }
126 }
127 }
128
129 /// <summary>
130 /// Create the entire inventory for a given user
131 /// </summary>
132 /// <param name="user"></param>
133 /// <returns></returns>
134 public bool CreateUserInventory(UUID userID)
135 {
136 NameValueCollection requestArgs = new NameValueCollection
137 {
138 { "RequestMethod", "AddInventory" },
139 { "OwnerID", userID.ToString() }
140 };
141
142 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
143 bool success = response["Success"].AsBoolean();
144
145 if (!success)
146 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString());
147
148 return success;
149 }
150
151 /// <summary>
152 /// Gets the skeleton of the inventory -- folders only
153 /// </summary>
154 /// <param name="userID"></param>
155 /// <returns></returns>
156 public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
157 {
158 NameValueCollection requestArgs = new NameValueCollection
159 {
160 { "RequestMethod", "GetInventoryNode" },
161 { "ItemID", userID.ToString() },
162 { "OwnerID", userID.ToString() },
163 { "IncludeFolders", "1" },
164 { "IncludeItems", "0" },
165 { "ChildrenOnly", "0" }
166 };
167
168 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
169 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
170 {
171 OSDArray items = (OSDArray)response["Items"];
172 return GetFoldersFromResponse(items, userID, true);
173 }
174 else
175 {
176 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " +
177 response["Message"].AsString());
178 return new List<InventoryFolderBase>(0);
179 }
180 }
181
182 /// <summary>
183 /// Synchronous inventory fetch.
184 /// </summary>
185 /// <param name="userID"></param>
186 /// <returns></returns>
187 [Obsolete]
188 public InventoryCollection GetUserInventory(UUID userID)
189 {
190 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
191
192 InventoryCollection inventory = new InventoryCollection();
193 inventory.UserID = userID;
194 inventory.Folders = new List<InventoryFolderBase>();
195 inventory.Items = new List<InventoryItemBase>();
196
197 return inventory;
198 }
199
200 /// <summary>
201 /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
202 /// inventory has been received
203 /// </summary>
204 /// <param name="userID"></param>
205 /// <param name="callback"></param>
206 [Obsolete]
207 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
208 {
209 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
210 callback(new List<InventoryFolderImpl>(0), new List<InventoryItemBase>(0));
211 }
212
213 /// <summary>
214 /// Retrieve the root inventory folder for the given user.
215 /// </summary>
216 /// <param name="userID"></param>
217 /// <returns>null if no root folder was found</returns>
218 public InventoryFolderBase GetRootFolder(UUID userID)
219 {
220 NameValueCollection requestArgs = new NameValueCollection
221 {
222 { "RequestMethod", "GetInventoryNode" },
223 { "ItemID", userID.ToString() },
224 { "OwnerID", userID.ToString() },
225 { "IncludeFolders", "1" },
226 { "IncludeItems", "0" },
227 { "ChildrenOnly", "1" }
228 };
229
230 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
231 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
232 {
233 OSDArray items = (OSDArray)response["Items"];
234 List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true);
235
236 if (folders.Count > 0)
237 return folders[0];
238 }
239
240 return null;
241 }
242
243 /// <summary>
244 /// Gets the user folder for the given folder-type
245 /// </summary>
246 /// <param name="userID"></param>
247 /// <param name="type"></param>
248 /// <returns></returns>
249 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
250 {
251 string contentType = SLUtil.SLAssetTypeToContentType((int)type);
252
253 NameValueCollection requestArgs = new NameValueCollection
254 {
255 { "RequestMethod", "GetFolderForType" },
256 { "ContentType", contentType },
257 { "OwnerID", userID.ToString() }
258 };
259
260 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
261 if (response["Success"].AsBoolean() && response["Folder"] is OSDMap)
262 {
263 OSDMap folder = (OSDMap)response["Folder"];
264
265 return new InventoryFolderBase(
266 folder["ID"].AsUUID(),
267 folder["Name"].AsString(),
268 folder["OwnerID"].AsUUID(),
269 (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()),
270 folder["ParentID"].AsUUID(),
271 (ushort)folder["Version"].AsInteger()
272 );
273 }
274 else
275 {
276 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Default folder not found for content type " + contentType + ": " + response["Message"].AsString());
277 return GetRootFolder(userID);
278 }
279 }
280
281 /// <summary>
282 /// Get an item, given by its UUID
283 /// </summary>
284 /// <param name="item"></param>
285 /// <returns></returns>
286 public InventoryItemBase GetItem(InventoryItemBase item)
287 {
288 NameValueCollection requestArgs = new NameValueCollection
289 {
290 { "RequestMethod", "GetInventoryNode" },
291 { "ItemID", item.ID.ToString() },
292 { "OwnerID", item.Owner.ToString() },
293 { "IncludeFolders", "1" },
294 { "IncludeItems", "1" },
295 { "ChildrenOnly", "1" }
296 };
297
298 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
299 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
300 {
301 List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]);
302 if (items.Count > 0)
303 {
304 // The requested item should be the first in this list, but loop through
305 // and sanity check just in case
306 for (int i = 0; i < items.Count; i++)
307 {
308 if (items[i].ID == item.ID)
309 return items[i];
310 }
311 }
312 }
313
314 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found");
315 return null;
316 }
317
318 /// <summary>
319 /// Get a folder, given by its UUID
320 /// </summary>
321 /// <param name="folder"></param>
322 /// <returns></returns>
323 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
324 {
325 NameValueCollection requestArgs = new NameValueCollection
326 {
327 { "RequestMethod", "GetInventoryNode" },
328 { "ItemID", folder.ID.ToString() },
329 { "OwnerID", folder.Owner.ToString() },
330 { "IncludeFolders", "1" },
331 { "IncludeItems", "0" },
332 { "ChildrenOnly", "1" }
333 };
334
335 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
336 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
337 {
338 OSDArray items = (OSDArray)response["Items"];
339 List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true);
340
341 if (folders.Count > 0)
342 return folders[0];
343 }
344
345 return null;
346 }
347
348 /// <summary>
349 /// Gets everything (folders and items) inside a folder
350 /// </summary>
351 /// <param name="userID"></param>
352 /// <param name="folderID"></param>
353 /// <returns></returns>
354 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
355 {
356 InventoryCollection inventory = new InventoryCollection();
357 inventory.UserID = userID;
358
359 NameValueCollection requestArgs = new NameValueCollection
360 {
361 { "RequestMethod", "GetInventoryNode" },
362 { "ItemID", folderID.ToString() },
363 { "OwnerID", userID.ToString() },
364 { "IncludeFolders", "1" },
365 { "IncludeItems", "1" },
366 { "ChildrenOnly", "1" }
367 };
368
369 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
370 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
371 {
372 OSDArray items = (OSDArray)response["Items"];
373
374 inventory.Folders = GetFoldersFromResponse(items, folderID, false);
375 inventory.Items = GetItemsFromResponse(items);
376 }
377 else
378 {
379 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " +
380 response["Message"].AsString());
381 inventory.Folders = new List<InventoryFolderBase>(0);
382 inventory.Items = new List<InventoryItemBase>(0);
383 }
384
385 return inventory;
386 }
387
388 /// <summary>
389 /// Gets the items inside a folder
390 /// </summary>
391 /// <param name="userID"></param>
392 /// <param name="folderID"></param>
393 /// <returns></returns>
394 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
395 {
396 InventoryCollection inventory = new InventoryCollection();
397 inventory.UserID = userID;
398
399 NameValueCollection requestArgs = new NameValueCollection
400 {
401 { "RequestMethod", "GetInventoryNode" },
402 { "ItemID", folderID.ToString() },
403 { "OwnerID", userID.ToString() },
404 { "IncludeFolders", "0" },
405 { "IncludeItems", "1" },
406 { "ChildrenOnly", "1" }
407 };
408
409 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
410 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
411 {
412 OSDArray items = (OSDArray)response["Items"];
413 return GetItemsFromResponse(items);
414 }
415 else
416 {
417 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " +
418 response["Message"].AsString());
419 return new List<InventoryItemBase>(0);
420 }
421 }
422
423 /// <summary>
424 /// Add a new folder to the user's inventory
425 /// </summary>
426 /// <param name="folder"></param>
427 /// <returns>true if the folder was successfully added</returns>
428 public bool AddFolder(InventoryFolderBase folder)
429 {
430 NameValueCollection requestArgs = new NameValueCollection
431 {
432 { "RequestMethod", "AddInventoryFolder" },
433 { "FolderID", folder.ID.ToString() },
434 { "ParentID", folder.ParentID.ToString() },
435 { "OwnerID", folder.Owner.ToString() },
436 { "Name", folder.Name },
437 { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) }
438 };
439
440 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
441 bool success = response["Success"].AsBoolean();
442
443 if (!success)
444 {
445 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " +
446 response["Message"].AsString());
447 }
448
449 return success;
450 }
451
452 /// <summary>
453 /// Update a folder in the user's inventory
454 /// </summary>
455 /// <param name="folder"></param>
456 /// <returns>true if the folder was successfully updated</returns>
457 public bool UpdateFolder(InventoryFolderBase folder)
458 {
459 return AddFolder(folder);
460 }
461
462 /// <summary>
463 /// Move an inventory folder to a new location
464 /// </summary>
465 /// <param name="folder">A folder containing the details of the new location</param>
466 /// <returns>true if the folder was successfully moved</returns>
467 public bool MoveFolder(InventoryFolderBase folder)
468 {
469 return AddFolder(folder);
470 }
471
472 /// <summary>
473 /// Delete an item from the user's inventory
474 /// </summary>
475 /// <param name="item"></param>
476 /// <returns>true if the item was successfully deleted</returns>
477 //bool DeleteItem(InventoryItemBase item);
478 public bool DeleteFolders(UUID userID, List<UUID> folderIDs)
479 {
480 return DeleteItems(userID, folderIDs);
481 }
482
483 /// <summary>
484 /// Delete an item from the user's inventory
485 /// </summary>
486 /// <param name="item"></param>
487 /// <returns>true if the item was successfully deleted</returns>
488 public bool DeleteItems(UUID userID, List<UUID> itemIDs)
489 {
490 // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes
491 bool allSuccess = true;
492
493 for (int i = 0; i < itemIDs.Count; i++)
494 {
495 UUID itemID = itemIDs[i];
496
497 NameValueCollection requestArgs = new NameValueCollection
498 {
499 { "RequestMethod", "RemoveInventoryNode" },
500 { "OwnerID", userID.ToString() },
501 { "ItemID", itemID.ToString() }
502 };
503
504 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
505 bool success = response["Success"].AsBoolean();
506
507 if (!success)
508 {
509 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " +
510 response["Message"].AsString());
511 allSuccess = false;
512 }
513 }
514
515 return allSuccess;
516 }
517
518 /// <summary>
519 /// Purge an inventory folder of all its items and subfolders.
520 /// </summary>
521 /// <param name="folder"></param>
522 /// <returns>true if the folder was successfully purged</returns>
523 public bool PurgeFolder(InventoryFolderBase folder)
524 {
525 NameValueCollection requestArgs = new NameValueCollection
526 {
527 { "RequestMethod", "PurgeInventoryFolder" },
528 { "OwnerID", folder.Owner.ToString() },
529 { "FolderID", folder.ID.ToString() }
530 };
531
532 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
533 bool success = response["Success"].AsBoolean();
534
535 if (!success)
536 {
537 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " +
538 response["Message"].AsString());
539 }
540
541 return success;
542 }
543
544 /// <summary>
545 /// Add a new item to the user's inventory
546 /// </summary>
547 /// <param name="item"></param>
548 /// <returns>true if the item was successfully added</returns>
549 public bool AddItem(InventoryItemBase item)
550 {
551 // A folder of UUID.Zero means we need to find the most appropriate home for this item
552 if (item.Folder == UUID.Zero)
553 {
554 InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType);
555 if (folder != null && folder.ID != UUID.Zero)
556 item.Folder = folder.ID;
557 else
558 item.Folder = item.Owner; // Root folder
559 }
560
561 if ((AssetType)item.AssetType == AssetType.Gesture)
562 UpdateGesture(item.Owner, item.ID, item.Flags == 1);
563
564 if (item.BasePermissions == 0)
565 m_log.WarnFormat("[SIMIAN INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID);
566
567 OSDMap permissions = new OSDMap
568 {
569 { "BaseMask", OSD.FromInteger(item.BasePermissions) },
570 { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) },
571 { "GroupMask", OSD.FromInteger(item.GroupPermissions) },
572 { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) },
573 { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) }
574 };
575
576 OSDMap extraData = new OSDMap()
577 {
578 { "Flags", OSD.FromInteger(item.Flags) },
579 { "GroupID", OSD.FromUUID(item.GroupID) },
580 { "GroupOwned", OSD.FromBoolean(item.GroupOwned) },
581 { "SalePrice", OSD.FromInteger(item.SalePrice) },
582 { "SaleType", OSD.FromInteger(item.SaleType) },
583 { "Permissions", permissions }
584 };
585
586 // Add different asset type only if it differs from inventory type
587 // (needed for links)
588 string invContentType = SLUtil.SLInvTypeToContentType(item.InvType);
589 string assetContentType = SLUtil.SLAssetTypeToContentType(item.AssetType);
590
591 if (invContentType != assetContentType)
592 extraData["LinkedItemType"] = OSD.FromString(assetContentType);
593
594 NameValueCollection requestArgs = new NameValueCollection
595 {
596 { "RequestMethod", "AddInventoryItem" },
597 { "ItemID", item.ID.ToString() },
598 { "AssetID", item.AssetID.ToString() },
599 { "ParentID", item.Folder.ToString() },
600 { "OwnerID", item.Owner.ToString() },
601 { "Name", item.Name },
602 { "Description", item.Description },
603 { "CreatorID", item.CreatorId },
604 { "ContentType", invContentType },
605 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
606 };
607
608 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
609 bool success = response["Success"].AsBoolean();
610
611 if (!success)
612 {
613 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " +
614 response["Message"].AsString());
615 }
616
617 return success;
618 }
619
620 /// <summary>
621 /// Update an item in the user's inventory
622 /// </summary>
623 /// <param name="item"></param>
624 /// <returns>true if the item was successfully updated</returns>
625 public bool UpdateItem(InventoryItemBase item)
626 {
627 if (item.AssetID != UUID.Zero)
628 {
629 return AddItem(item);
630 }
631 else
632 {
633 // This is actually a folder update
634 InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0);
635 return UpdateFolder(folder);
636 }
637 }
638
639 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
640 {
641 bool success = true;
642
643 while (items.Count > 0)
644 {
645 List<InventoryItemBase> currentItems = new List<InventoryItemBase>();
646 UUID destFolderID = items[0].Folder;
647
648 // Find all of the items being moved to the current destination folder
649 for (int i = 0; i < items.Count; i++)
650 {
651 InventoryItemBase item = items[i];
652 if (item.Folder == destFolderID)
653 currentItems.Add(item);
654 }
655
656 // Do the inventory move for the current items
657 success &= MoveItems(ownerID, items, destFolderID);
658
659 // Remove the processed items from the list
660 for (int i = 0; i < currentItems.Count; i++)
661 items.Remove(currentItems[i]);
662 }
663
664 return success;
665 }
666
667 /// <summary>
668 /// Does the given user have an inventory structure?
669 /// </summary>
670 /// <param name="userID"></param>
671 /// <returns></returns>
672 public bool HasInventoryForUser(UUID userID)
673 {
674 return GetRootFolder(userID) != null;
675 }
676
677 /// <summary>
678 /// Get the active gestures of the agent.
679 /// </summary>
680 /// <param name="userID"></param>
681 /// <returns></returns>
682 public List<InventoryItemBase> GetActiveGestures(UUID userID)
683 {
684 OSDArray items = FetchGestures(userID);
685
686 string[] itemIDs = new string[items.Count];
687 for (int i = 0; i < items.Count; i++)
688 itemIDs[i] = items[i].AsUUID().ToString();
689
690 NameValueCollection requestArgs = new NameValueCollection
691 {
692 { "RequestMethod", "GetInventoryNodes" },
693 { "OwnerID", userID.ToString() },
694 { "Items", String.Join(",", itemIDs) }
695 };
696
697 // FIXME: Implement this in SimianGrid
698 return new List<InventoryItemBase>(0);
699 }
700
701 /// <summary>
702 /// Get the union of permissions of all inventory items
703 /// that hold the given assetID.
704 /// </summary>
705 /// <param name="userID"></param>
706 /// <param name="assetID"></param>
707 /// <returns>The permissions or 0 if no such asset is found in
708 /// the user's inventory</returns>
709 public int GetAssetPermissions(UUID userID, UUID assetID)
710 {
711 NameValueCollection requestArgs = new NameValueCollection
712 {
713 { "RequestMethod", "GetInventoryNodes" },
714 { "OwnerID", userID.ToString() },
715 { "AssetID", assetID.ToString() }
716 };
717
718 // FIXME: Implement this in SimianGrid
719 return (int)PermissionMask.All;
720 }
721
722 private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder)
723 {
724 List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count);
725
726 for (int i = 0; i < items.Count; i++)
727 {
728 OSDMap item = items[i] as OSDMap;
729
730 if (item != null && item["Type"].AsString() == "Folder")
731 {
732 UUID folderID = item["ID"].AsUUID();
733
734 if (folderID == baseFolder && !includeBaseFolder)
735 continue;
736
737 invFolders.Add(new InventoryFolderBase(
738 folderID,
739 item["Name"].AsString(),
740 item["OwnerID"].AsUUID(),
741 (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()),
742 item["ParentID"].AsUUID(),
743 (ushort)item["Version"].AsInteger()
744 ));
745 }
746 }
747
748 return invFolders;
749 }
750
751 private List<InventoryItemBase> GetItemsFromResponse(OSDArray items)
752 {
753 List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count);
754
755 for (int i = 0; i < items.Count; i++)
756 {
757 OSDMap item = items[i] as OSDMap;
758
759 if (item != null && item["Type"].AsString() == "Item")
760 {
761 InventoryItemBase invItem = new InventoryItemBase();
762
763 invItem.AssetID = item["AssetID"].AsUUID();
764 invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString());
765 invItem.CreationDate = item["CreationDate"].AsInteger();
766 invItem.CreatorId = item["CreatorID"].AsString();
767 invItem.CreatorIdAsUuid = item["CreatorID"].AsUUID();
768 invItem.Description = item["Description"].AsString();
769 invItem.Folder = item["ParentID"].AsUUID();
770 invItem.ID = item["ID"].AsUUID();
771 invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString());
772 invItem.Name = item["Name"].AsString();
773 invItem.Owner = item["OwnerID"].AsUUID();
774
775 OSDMap extraData = item["ExtraData"] as OSDMap;
776 if (extraData != null && extraData.Count > 0)
777 {
778 invItem.Flags = extraData["Flags"].AsUInteger();
779 invItem.GroupID = extraData["GroupID"].AsUUID();
780 invItem.GroupOwned = extraData["GroupOwned"].AsBoolean();
781 invItem.SalePrice = extraData["SalePrice"].AsInteger();
782 invItem.SaleType = (byte)extraData["SaleType"].AsInteger();
783
784 OSDMap perms = extraData["Permissions"] as OSDMap;
785 if (perms != null)
786 {
787 invItem.BasePermissions = perms["BaseMask"].AsUInteger();
788 invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger();
789 invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger();
790 invItem.GroupPermissions = perms["GroupMask"].AsUInteger();
791 invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger();
792 }
793
794 if (extraData.ContainsKey("LinkedItemType"))
795 invItem.AssetType = SLUtil.ContentTypeToSLAssetType(extraData["LinkedItemType"].AsString());
796 }
797
798 if (invItem.BasePermissions == 0)
799 {
800 m_log.InfoFormat("[SIMIAN INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})",
801 invItem.Name, invItem.ID);
802 invItem.BasePermissions = (uint)PermissionMask.All;
803 invItem.CurrentPermissions = (uint)PermissionMask.All;
804 invItem.EveryOnePermissions = (uint)PermissionMask.All;
805 invItem.GroupPermissions = (uint)PermissionMask.All;
806 invItem.NextPermissions = (uint)PermissionMask.All;
807 }
808
809 invItems.Add(invItem);
810 }
811 }
812
813 return invItems;
814 }
815
816 private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID)
817 {
818 string[] itemIDs = new string[items.Count];
819 for (int i = 0; i < items.Count; i++)
820 itemIDs[i] = items[i].ID.ToString();
821
822 NameValueCollection requestArgs = new NameValueCollection
823 {
824 { "RequestMethod", "MoveInventoryNodes" },
825 { "OwnerID", ownerID.ToString() },
826 { "FolderID", destFolderID.ToString() },
827 { "Items", String.Join(",", itemIDs) }
828 };
829
830 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
831 bool success = response["Success"].AsBoolean();
832
833 if (!success)
834 {
835 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " +
836 destFolderID + ": " + response["Message"].AsString());
837 }
838
839 return success;
840 }
841
842 private void UpdateGesture(UUID userID, UUID itemID, bool enabled)
843 {
844 OSDArray gestures = FetchGestures(userID);
845 OSDArray newGestures = new OSDArray();
846
847 for (int i = 0; i < gestures.Count; i++)
848 {
849 UUID gesture = gestures[i].AsUUID();
850 if (gesture != itemID)
851 newGestures.Add(OSD.FromUUID(gesture));
852 }
853
854 if (enabled)
855 newGestures.Add(OSD.FromUUID(itemID));
856
857 SaveGestures(userID, newGestures);
858 }
859
860 private OSDArray FetchGestures(UUID userID)
861 {
862 NameValueCollection requestArgs = new NameValueCollection
863 {
864 { "RequestMethod", "GetUser" },
865 { "UserID", userID.ToString() }
866 };
867
868 OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs);
869 if (response["Success"].AsBoolean())
870 {
871 OSDMap user = response["User"] as OSDMap;
872 if (user != null && response.ContainsKey("Gestures"))
873 {
874 OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString());
875 if (gestures != null && gestures is OSDArray)
876 return (OSDArray)gestures;
877 else
878 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID);
879 }
880 }
881 else
882 {
883 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " +
884 response["Message"].AsString());
885 }
886
887 return new OSDArray();
888 }
889
890 private void SaveGestures(UUID userID, OSDArray gestures)
891 {
892 NameValueCollection requestArgs = new NameValueCollection
893 {
894 { "RequestMethod", "AddUserData" },
895 { "UserID", userID.ToString() },
896 { "Gestures", OSDParser.SerializeJsonString(gestures) }
897 };
898
899 OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs);
900 if (!response["Success"].AsBoolean())
901 {
902 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " +
903 response["Message"].AsString());
904 }
905 }
906 }
907}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
new file mode 100644
index 0000000..b86c45c
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
@@ -0,0 +1,575 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.Net;
32using System.Reflection;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Server.Base;
42using OpenMetaverse;
43using OpenMetaverse.StructuredData;
44
45using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
46
47namespace OpenSim.Services.Connectors.SimianGrid
48{
49 /// <summary>
50 /// Connects avatar presence information (for tracking current location and
51 /// message routing) to the SimianGrid backend
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
54 public class SimianPresenceServiceConnector : IPresenceService, IGridUserService, ISharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(
58 MethodBase.GetCurrentMethod().DeclaringType);
59
60 private string m_serverUrl = String.Empty;
61
62 #region ISharedRegionModule
63
64 public Type ReplaceableInterface { get { return null; } }
65 public void RegionLoaded(Scene scene) { }
66 public void PostInitialise() { }
67 public void Close() { }
68
69 public SimianPresenceServiceConnector() { }
70 public string Name { get { return "SimianPresenceServiceConnector"; } }
71 public void AddRegion(Scene scene)
72 {
73 if (!String.IsNullOrEmpty(m_serverUrl))
74 {
75 scene.RegisterModuleInterface<IPresenceService>(this);
76 scene.RegisterModuleInterface<IGridUserService>(this);
77
78 scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler;
79 scene.EventManager.OnNewClient += NewClientHandler;
80 scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler;
81
82 LogoutRegionAgents(scene.RegionInfo.RegionID);
83 }
84 }
85 public void RemoveRegion(Scene scene)
86 {
87 if (!String.IsNullOrEmpty(m_serverUrl))
88 {
89 scene.UnregisterModuleInterface<IPresenceService>(this);
90 scene.UnregisterModuleInterface<IGridUserService>(this);
91
92 scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler;
93 scene.EventManager.OnNewClient -= NewClientHandler;
94 scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler;
95
96 LogoutRegionAgents(scene.RegionInfo.RegionID);
97 }
98 }
99
100 #endregion ISharedRegionModule
101
102 public SimianPresenceServiceConnector(IConfigSource source)
103 {
104 Initialise(source);
105 }
106
107 public void Initialise(IConfigSource source)
108 {
109 if (Simian.IsSimianEnabled(source, "PresenceServices", this.Name))
110 {
111 IConfig gridConfig = source.Configs["PresenceService"];
112 if (gridConfig == null)
113 {
114 m_log.Error("[SIMIAN PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini");
115 throw new Exception("Presence connector init error");
116 }
117
118 string serviceUrl = gridConfig.GetString("PresenceServerURI");
119 if (String.IsNullOrEmpty(serviceUrl))
120 {
121 m_log.Error("[SIMIAN PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService");
122 throw new Exception("Presence connector init error");
123 }
124
125 m_serverUrl = serviceUrl;
126 }
127 }
128
129 #region IPresenceService
130
131 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
132 {
133 m_log.ErrorFormat("[SIMIAN PRESENCE CONNECTOR]: Login requested, UserID={0}, SessionID={1}, SecureSessionID={2}",
134 userID, sessionID, secureSessionID);
135
136 NameValueCollection requestArgs = new NameValueCollection
137 {
138 { "RequestMethod", "AddSession" },
139 { "UserID", userID.ToString() }
140 };
141 if (sessionID != UUID.Zero)
142 {
143 requestArgs["SessionID"] = sessionID.ToString();
144 requestArgs["SecureSessionID"] = secureSessionID.ToString();
145 }
146
147 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
148 bool success = response["Success"].AsBoolean();
149
150 if (!success)
151 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to login agent " + userID + ": " + response["Message"].AsString());
152
153 return success;
154 }
155
156 public bool LogoutAgent(UUID sessionID)
157 {
158 m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
159
160 NameValueCollection requestArgs = new NameValueCollection
161 {
162 { "RequestMethod", "RemoveSession" },
163 { "SessionID", sessionID.ToString() }
164 };
165
166 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
167 bool success = response["Success"].AsBoolean();
168
169 if (!success)
170 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to logout agent with sessionID " + sessionID + ": " + response["Message"].AsString());
171
172 return success;
173 }
174
175 public bool LogoutRegionAgents(UUID regionID)
176 {
177 m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
178
179 NameValueCollection requestArgs = new NameValueCollection
180 {
181 { "RequestMethod", "RemoveSessions" },
182 { "SceneID", regionID.ToString() }
183 };
184
185 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
186 bool success = response["Success"].AsBoolean();
187
188 if (!success)
189 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to logout agents from region " + regionID + ": " + response["Message"].AsString());
190
191 return success;
192 }
193
194 public bool ReportAgent(UUID sessionID, UUID regionID)
195 {
196 return ReportAgent(sessionID, regionID, Vector3.Zero, Vector3.Zero);
197 }
198
199 protected bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
200 {
201 //m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Updating session data for agent with sessionID " + sessionID);
202
203 NameValueCollection requestArgs = new NameValueCollection
204 {
205 { "RequestMethod", "UpdateSession" },
206 { "SessionID", sessionID.ToString() },
207 { "SceneID", regionID.ToString() },
208 { "ScenePosition", position.ToString() },
209 { "SceneLookAt", lookAt.ToString() }
210 };
211
212 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
213 bool success = response["Success"].AsBoolean();
214
215 if (!success)
216 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
217
218 return success;
219 }
220
221 public PresenceInfo GetAgent(UUID sessionID)
222 {
223 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID);
224
225 NameValueCollection requestArgs = new NameValueCollection
226 {
227 { "RequestMethod", "GetSession" },
228 { "SessionID", sessionID.ToString() }
229 };
230
231 OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
232 if (sessionResponse["Success"].AsBoolean())
233 {
234 UUID userID = sessionResponse["UserID"].AsUUID();
235 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
236
237 requestArgs = new NameValueCollection
238 {
239 { "RequestMethod", "GetUser" },
240 { "UserID", userID.ToString() }
241 };
242
243 OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
244 if (userResponse["Success"].AsBoolean())
245 return ResponseToPresenceInfo(sessionResponse, userResponse);
246 else
247 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
248 }
249 else
250 {
251 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString());
252 }
253
254 return null;
255 }
256
257 public PresenceInfo[] GetAgents(string[] userIDs)
258 {
259 List<PresenceInfo> presences = new List<PresenceInfo>(userIDs.Length);
260
261 for (int i = 0; i < userIDs.Length; i++)
262 {
263 UUID userID;
264 if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero)
265 presences.AddRange(GetSessions(userID));
266 }
267
268 return presences.ToArray();
269 }
270
271 #endregion IPresenceService
272
273 #region IGridUserService
274
275 public GridUserInfo LoggedIn(string userID)
276 {
277 // never implemented at the sim
278 return null;
279 }
280
281 public bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
282 {
283 // Not needed for simian grid, event handler is doing it
284 return true;
285 }
286
287 public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
288 {
289 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID);
290
291 NameValueCollection requestArgs = new NameValueCollection
292 {
293 { "RequestMethod", "AddUserData" },
294 { "UserID", userID.ToString() },
295 { "HomeLocation", SerializeLocation(regionID, position, lookAt) }
296 };
297
298 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
299 bool success = response["Success"].AsBoolean();
300
301 if (!success)
302 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to set home location for " + userID + ": " + response["Message"].AsString());
303
304 return success;
305 }
306
307 public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
308 {
309 // Not needed for simian grid, presence detection is doing it
310 return true;
311 }
312
313 public GridUserInfo GetGridUserInfo(string user)
314 {
315 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user);
316
317 UUID userID = new UUID(user);
318 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
319
320 NameValueCollection requestArgs = new NameValueCollection
321 {
322 { "RequestMethod", "GetUser" },
323 { "UserID", userID.ToString() }
324 };
325
326 OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
327 if (userResponse["Success"].AsBoolean())
328 return ResponseToGridUserInfo(userResponse);
329 else
330 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
331
332 return null;
333 }
334
335 #endregion
336
337 #region Presence Detection
338
339 private void MakeRootAgentHandler(ScenePresence sp)
340 {
341 m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
342
343 ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
344 SetLastLocation(sp.UUID, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
345 }
346
347 private void NewClientHandler(IClientAPI client)
348 {
349 client.OnConnectionClosed += LogoutHandler;
350 }
351
352 private void SignificantClientMovementHandler(IClientAPI client)
353 {
354 ScenePresence sp;
355 if (client.Scene is Scene && ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out sp))
356 ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
357 }
358
359 private void LogoutHandler(IClientAPI client)
360 {
361 if (client.IsLoggingOut)
362 {
363 client.OnConnectionClosed -= LogoutHandler;
364
365 object obj;
366 if (client.Scene.TryGetScenePresence(client.AgentId, out obj) && obj is ScenePresence)
367 {
368 // The avatar is still in the scene, we can get the exact logout position
369 ScenePresence sp = (ScenePresence)obj;
370 SetLastLocation(client.AgentId, client.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
371 }
372 else
373 {
374 // The avatar was already removed from the scene, store LastLocation using the most recent session data
375 m_log.Warn("[PRESENCE]: " + client.Name + " has already been removed from the scene, storing approximate LastLocation");
376 SetLastLocation(client.SessionId);
377 }
378
379 LogoutAgent(client.SessionId);
380 }
381 }
382
383 #endregion Presence Detection
384
385 #region Helpers
386
387 private OSDMap GetUserData(UUID userID)
388 {
389 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
390
391 NameValueCollection requestArgs = new NameValueCollection
392 {
393 { "RequestMethod", "GetUser" },
394 { "UserID", userID.ToString() }
395 };
396
397 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
398 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
399 return response;
400 else
401 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString());
402
403 return null;
404 }
405
406 private OSDMap GetSessionData(UUID sessionID)
407 {
408 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for session " + sessionID);
409
410 NameValueCollection requestArgs = new NameValueCollection
411 {
412 { "RequestMethod", "GetSession" },
413 { "SessionID", sessionID.ToString() }
414 };
415
416 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
417 if (response["Success"].AsBoolean())
418 return response;
419 else
420 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session data for session " + sessionID);
421
422 return null;
423 }
424
425 private List<PresenceInfo> GetSessions(UUID userID)
426 {
427 List<PresenceInfo> presences = new List<PresenceInfo>(1);
428
429 OSDMap userResponse = GetUserData(userID);
430 if (userResponse != null)
431 {
432 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting sessions for " + userID);
433
434 NameValueCollection requestArgs = new NameValueCollection
435 {
436 { "RequestMethod", "GetSession" },
437 { "UserID", userID.ToString() }
438 };
439
440 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
441 if (response["Success"].AsBoolean())
442 {
443 PresenceInfo presence = ResponseToPresenceInfo(response, userResponse);
444 if (presence != null)
445 presences.Add(presence);
446 }
447 else
448 {
449 m_log.Debug("[SIMIAN PRESENCE CONNECTOR]: No session returned for " + userID + ": " + response["Message"].AsString());
450 }
451 }
452
453 return presences;
454 }
455
456 /// <summary>
457 /// Fetch the last known avatar location with GetSession and persist it
458 /// as user data with AddUserData
459 /// </summary>
460 private bool SetLastLocation(UUID sessionID)
461 {
462 NameValueCollection requestArgs = new NameValueCollection
463 {
464 { "RequestMethod", "GetSession" },
465 { "SessionID", sessionID.ToString() }
466 };
467
468 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
469 bool success = response["Success"].AsBoolean();
470
471 if (success)
472 {
473 UUID userID = response["UserID"].AsUUID();
474 UUID sceneID = response["SceneID"].AsUUID();
475 Vector3 position = response["ScenePosition"].AsVector3();
476 Vector3 lookAt = response["SceneLookAt"].AsVector3();
477
478 return SetLastLocation(userID, sceneID, position, lookAt);
479 }
480 else
481 {
482 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
483 " while saving last location: " + response["Message"].AsString());
484 }
485
486 return success;
487 }
488
489 private bool SetLastLocation(UUID userID, UUID sceneID, Vector3 position, Vector3 lookAt)
490 {
491 NameValueCollection requestArgs = new NameValueCollection
492 {
493 { "RequestMethod", "AddUserData" },
494 { "UserID", userID.ToString() },
495 { "LastLocation", SerializeLocation(sceneID, position, lookAt) }
496 };
497
498 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
499 bool success = response["Success"].AsBoolean();
500
501 if (!success)
502 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
503
504 return success;
505 }
506
507 private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
508 {
509 if (sessionResponse == null)
510 return null;
511
512 PresenceInfo info = new PresenceInfo();
513
514 info.UserID = sessionResponse["UserID"].AsUUID().ToString();
515 info.RegionID = sessionResponse["SceneID"].AsUUID();
516
517 return info;
518 }
519
520 private GridUserInfo ResponseToGridUserInfo(OSDMap userResponse)
521 {
522 if (userResponse != null && userResponse["User"] is OSDMap)
523 {
524
525 GridUserInfo info = new GridUserInfo();
526
527 info.Online = true;
528 info.UserID = userResponse["UserID"].AsUUID().ToString();
529 info.LastRegionID = userResponse["SceneID"].AsUUID();
530 info.LastPosition = userResponse["ScenePosition"].AsVector3();
531 info.LastLookAt = userResponse["SceneLookAt"].AsVector3();
532
533 OSDMap user = (OSDMap)userResponse["User"];
534
535 info.Login = user["LastLoginDate"].AsDate();
536 info.Logout = user["LastLogoutDate"].AsDate();
537 DeserializeLocation(user["HomeLocation"].AsString(), out info.HomeRegionID, out info.HomePosition, out info.HomeLookAt);
538
539 return info;
540 }
541
542 return null;
543 }
544
545 private string SerializeLocation(UUID regionID, Vector3 position, Vector3 lookAt)
546 {
547 return "{" + String.Format("\"SceneID\":\"{0}\",\"Position\":\"{1}\",\"LookAt\":\"{2}\"", regionID, position, lookAt) + "}";
548 }
549
550 private bool DeserializeLocation(string location, out UUID regionID, out Vector3 position, out Vector3 lookAt)
551 {
552 OSDMap map = null;
553
554 try { map = OSDParser.DeserializeJson(location) as OSDMap; }
555 catch { }
556
557 if (map != null)
558 {
559 regionID = map["SceneID"].AsUUID();
560 if (Vector3.TryParse(map["Position"].AsString(), out position) &&
561 Vector3.TryParse(map["LookAt"].AsString(), out lookAt))
562 {
563 return true;
564 }
565 }
566
567 regionID = UUID.Zero;
568 position = Vector3.Zero;
569 lookAt = Vector3.Zero;
570 return false;
571 }
572
573 #endregion Helpers
574 }
575}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
new file mode 100644
index 0000000..fbf4648
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
@@ -0,0 +1,435 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.Reflection;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Framework.Client;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Avatar profile flags
47 /// </summary>
48 [Flags]
49 public enum ProfileFlags : uint
50 {
51 AllowPublish = 1,
52 MaturePublish = 2,
53 Identified = 4,
54 Transacted = 8,
55 Online = 16
56 }
57
58 /// <summary>
59 /// Connects avatar profile and classified queries to the SimianGrid
60 /// backend
61 /// </summary>
62 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
63 public class SimianProfiles : INonSharedRegionModule
64 {
65 private static readonly ILog m_log =
66 LogManager.GetLogger(
67 MethodBase.GetCurrentMethod().DeclaringType);
68
69 private string m_serverUrl = String.Empty;
70
71 #region INonSharedRegionModule
72
73 public Type ReplaceableInterface { get { return null; } }
74 public void RegionLoaded(Scene scene) { }
75 public void Close() { }
76
77 public SimianProfiles() { }
78 public string Name { get { return "SimianProfiles"; } }
79 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { CheckEstateManager(scene); scene.EventManager.OnClientConnect += ClientConnectHandler; } }
80 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.EventManager.OnClientConnect -= ClientConnectHandler; } }
81
82 #endregion INonSharedRegionModule
83
84 public SimianProfiles(IConfigSource source)
85 {
86 Initialise(source);
87 }
88
89 public void Initialise(IConfigSource source)
90 {
91 if (Simian.IsSimianEnabled(source, "UserAccountServices", this.Name))
92 {
93 IConfig gridConfig = source.Configs["UserAccountService"];
94 if (gridConfig == null)
95 {
96 m_log.Error("[SIMIAN PROFILES]: UserAccountService missing from OpenSim.ini");
97 throw new Exception("Profiles init error");
98 }
99
100 string serviceUrl = gridConfig.GetString("UserAccountServerURI");
101 if (String.IsNullOrEmpty(serviceUrl))
102 {
103 m_log.Error("[SIMIAN PROFILES]: No UserAccountServerURI in section UserAccountService");
104 throw new Exception("Profiles init error");
105 }
106
107 if (!serviceUrl.EndsWith("/"))
108 serviceUrl = serviceUrl + '/';
109
110 m_serverUrl = serviceUrl;
111 }
112 }
113
114 private void ClientConnectHandler(IClientCore clientCore)
115 {
116 if (clientCore is IClientAPI)
117 {
118 IClientAPI client = (IClientAPI)clientCore;
119
120 // Classifieds
121 client.AddGenericPacketHandler("avatarclassifiedsrequest", AvatarClassifiedsRequestHandler);
122 client.OnClassifiedInfoRequest += ClassifiedInfoRequestHandler;
123 client.OnClassifiedInfoUpdate += ClassifiedInfoUpdateHandler;
124 client.OnClassifiedDelete += ClassifiedDeleteHandler;
125
126 // Picks
127 client.AddGenericPacketHandler("avatarpicksrequest", HandleAvatarPicksRequest);
128 client.AddGenericPacketHandler("pickinforequest", HandlePickInfoRequest);
129 client.OnPickInfoUpdate += PickInfoUpdateHandler;
130 client.OnPickDelete += PickDeleteHandler;
131
132 // Notes
133 client.AddGenericPacketHandler("avatarnotesrequest", HandleAvatarNotesRequest);
134 client.OnAvatarNotesUpdate += AvatarNotesUpdateHandler;
135
136 // Profiles
137 client.OnRequestAvatarProperties += RequestAvatarPropertiesHandler;
138 client.OnUpdateAvatarProperties += UpdateAvatarPropertiesHandler;
139 client.OnAvatarInterestUpdate += AvatarInterestUpdateHandler;
140 client.OnUserInfoRequest += UserInfoRequestHandler;
141 client.OnUpdateUserInfo += UpdateUserInfoHandler;
142 }
143 }
144
145 #region Classifieds
146
147 private void AvatarClassifiedsRequestHandler(Object sender, string method, List<String> args)
148 {
149 if (!(sender is IClientAPI))
150 return;
151 IClientAPI client = (IClientAPI)sender;
152
153 UUID targetAvatarID;
154 if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
155 {
156 m_log.Error("[SIMIAN PROFILES]: Unrecognized arguments for " + method);
157 return;
158 }
159
160 // FIXME: Query the generic key/value store for classifieds
161 client.SendAvatarClassifiedReply(targetAvatarID, new Dictionary<UUID, string>(0));
162 }
163
164 private void ClassifiedInfoRequestHandler(UUID classifiedID, IClientAPI client)
165 {
166 // FIXME: Fetch this info
167 client.SendClassifiedInfoReply(classifiedID, UUID.Zero, 0, Utils.DateTimeToUnixTime(DateTime.UtcNow + TimeSpan.FromDays(1)),
168 0, String.Empty, String.Empty, UUID.Zero, 0, UUID.Zero, String.Empty, Vector3.Zero, String.Empty, 0, 0);
169 }
170
171 private void ClassifiedInfoUpdateHandler(UUID classifiedID, uint category, string name, string description,
172 UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price,
173 IClientAPI client)
174 {
175 // FIXME: Save this info
176 }
177
178 private void ClassifiedDeleteHandler(UUID classifiedID, IClientAPI client)
179 {
180 // FIXME: Delete the specified classified ad
181 }
182
183 #endregion Classifieds
184
185 #region Picks
186
187 private void HandleAvatarPicksRequest(Object sender, string method, List<String> args)
188 {
189 if (!(sender is IClientAPI))
190 return;
191 IClientAPI client = (IClientAPI)sender;
192
193 UUID targetAvatarID;
194 if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
195 {
196 m_log.Error("[SIMIAN PROFILES]: Unrecognized arguments for " + method);
197 return;
198 }
199
200 // FIXME: Fetch these
201 client.SendAvatarPicksReply(targetAvatarID, new Dictionary<UUID, string>(0));
202 }
203
204 private void HandlePickInfoRequest(Object sender, string method, List<String> args)
205 {
206 if (!(sender is IClientAPI))
207 return;
208 IClientAPI client = (IClientAPI)sender;
209
210 UUID avatarID;
211 UUID pickID;
212 if (args.Count < 2 || !UUID.TryParse(args[0], out avatarID) || !UUID.TryParse(args[1], out pickID))
213 {
214 m_log.Error("[SIMIAN PROFILES]: Unrecognized arguments for " + method);
215 return;
216 }
217
218 // FIXME: Fetch this
219 client.SendPickInfoReply(pickID, avatarID, false, UUID.Zero, String.Empty, String.Empty, UUID.Zero, String.Empty,
220 String.Empty, String.Empty, Vector3.Zero, 0, false);
221 }
222
223 private void PickInfoUpdateHandler(IClientAPI client, UUID pickID, UUID creatorID, bool topPick, string name,
224 string desc, UUID snapshotID, int sortOrder, bool enabled)
225 {
226 // FIXME: Save this
227 }
228
229 private void PickDeleteHandler(IClientAPI client, UUID pickID)
230 {
231 // FIXME: Delete
232 }
233
234 #endregion Picks
235
236 #region Notes
237
238 private void HandleAvatarNotesRequest(Object sender, string method, List<String> args)
239 {
240 if (!(sender is IClientAPI))
241 return;
242 IClientAPI client = (IClientAPI)sender;
243
244 UUID targetAvatarID;
245 if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
246 {
247 m_log.Error("[SIMIAN PROFILES]: Unrecognized arguments for " + method);
248 return;
249 }
250
251 // FIXME: Fetch this
252 client.SendAvatarNotesReply(targetAvatarID, String.Empty);
253 }
254
255 private void AvatarNotesUpdateHandler(IClientAPI client, UUID targetID, string notes)
256 {
257 // FIXME: Save this
258 }
259
260 #endregion Notes
261
262 #region Profiles
263
264 private void RequestAvatarPropertiesHandler(IClientAPI client, UUID avatarID)
265 {
266 OSDMap user = FetchUserData(avatarID);
267
268 ProfileFlags flags = ProfileFlags.AllowPublish | ProfileFlags.MaturePublish;
269
270 if (user != null)
271 {
272 OSDMap about = null;
273 if (user.ContainsKey("LLAbout"))
274 {
275 try { about = OSDParser.DeserializeJson(user["LLAbout"].AsString()) as OSDMap; }
276 catch { }
277 }
278
279 if (about == null)
280 about = new OSDMap(0);
281
282 // Check if this user is a grid operator
283 byte[] charterMember;
284 if (user["AccessLevel"].AsInteger() >= 200)
285 charterMember = Utils.StringToBytes("Operator");
286 else
287 charterMember = Utils.EmptyBytes;
288
289 // Check if the user is online
290 if (client.Scene is Scene)
291 {
292 OpenSim.Services.Interfaces.PresenceInfo[] presences = ((Scene)client.Scene).PresenceService.GetAgents(new string[] { avatarID.ToString() });
293 if (presences != null && presences.Length > 0)
294 flags |= ProfileFlags.Online;
295 }
296
297 // Check if the user is identified
298 if (user["Identified"].AsBoolean())
299 flags |= ProfileFlags.Identified;
300
301 client.SendAvatarProperties(avatarID, about["About"].AsString(), user["CreationDate"].AsDate().ToString("M/d/yyyy",
302 System.Globalization.CultureInfo.InvariantCulture), charterMember, about["FLAbout"].AsString(), (uint)flags,
303 about["FLImage"].AsUUID(), about["Image"].AsUUID(), about["URL"].AsString(), user["Partner"].AsUUID());
304
305 }
306 else
307 {
308 m_log.Warn("[SIMIAN PROFILES]: Failed to fetch profile information for " + client.Name + ", returning default values");
309 client.SendAvatarProperties(avatarID, String.Empty, "1/1/1970", Utils.EmptyBytes,
310 String.Empty, (uint)flags, UUID.Zero, UUID.Zero, String.Empty, UUID.Zero);
311 }
312 }
313
314 private void UpdateAvatarPropertiesHandler(IClientAPI client, UserProfileData profileData)
315 {
316 OSDMap map = new OSDMap
317 {
318 { "About", OSD.FromString(profileData.AboutText) },
319 { "Image", OSD.FromUUID(profileData.Image) },
320 { "FLAbout", OSD.FromString(profileData.FirstLifeAboutText) },
321 { "FLImage", OSD.FromUUID(profileData.FirstLifeImage) },
322 { "URL", OSD.FromString(profileData.ProfileUrl) }
323 };
324
325 AddUserData(client.AgentId, "LLAbout", map);
326 }
327
328 private void AvatarInterestUpdateHandler(IClientAPI client, uint wantmask, string wanttext, uint skillsmask,
329 string skillstext, string languages)
330 {
331 OSDMap map = new OSDMap
332 {
333 { "WantMask", OSD.FromInteger(wantmask) },
334 { "WantText", OSD.FromString(wanttext) },
335 { "SkillsMask", OSD.FromInteger(skillsmask) },
336 { "SkillsText", OSD.FromString(skillstext) },
337 { "Languages", OSD.FromString(languages) }
338 };
339
340 AddUserData(client.AgentId, "LLInterests", map);
341 }
342
343 private void UserInfoRequestHandler(IClientAPI client)
344 {
345 m_log.Error("[SIMIAN PROFILES]: UserInfoRequestHandler");
346
347 // Fetch this user's e-mail address
348 NameValueCollection requestArgs = new NameValueCollection
349 {
350 { "RequestMethod", "GetUser" },
351 { "UserID", client.AgentId.ToString() }
352 };
353
354 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
355 string email = response["Email"].AsString();
356
357 if (!response["Success"].AsBoolean())
358 m_log.Warn("[SIMIAN PROFILES]: GetUser failed during a user info request for " + client.Name);
359
360 client.SendUserInfoReply(false, true, email);
361 }
362
363 private void UpdateUserInfoHandler(bool imViaEmail, bool visible, IClientAPI client)
364 {
365 m_log.Info("[SIMIAN PROFILES]: Ignoring user info update from " + client.Name);
366 }
367
368 #endregion Profiles
369
370 /// <summary>
371 /// Sanity checks regions for a valid estate owner at startup
372 /// </summary>
373 private void CheckEstateManager(Scene scene)
374 {
375 EstateSettings estate = scene.RegionInfo.EstateSettings;
376
377 if (estate.EstateOwner == UUID.Zero)
378 {
379 // Attempt to lookup the grid admin
380 UserAccount admin = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, UUID.Zero);
381 if (admin != null)
382 {
383 m_log.InfoFormat("[SIMIAN PROFILES]: Setting estate {0} (ID: {1}) owner to {2}", estate.EstateName,
384 estate.EstateID, admin.Name);
385
386 estate.EstateOwner = admin.PrincipalID;
387 estate.Save();
388 }
389 else
390 {
391 m_log.WarnFormat("[SIMIAN PROFILES]: Estate {0} (ID: {1}) does not have an owner", estate.EstateName, estate.EstateID);
392 }
393 }
394 }
395
396 private bool AddUserData(UUID userID, string key, OSDMap value)
397 {
398 NameValueCollection requestArgs = new NameValueCollection
399 {
400 { "RequestMethod", "AddUserData" },
401 { "UserID", userID.ToString() },
402 { key, OSDParser.SerializeJsonString(value) }
403 };
404
405 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
406 bool success = response["Success"].AsBoolean();
407
408 if (!success)
409 m_log.WarnFormat("[SIMIAN PROFILES]: Failed to add user data with key {0} for {1}: {2}", key, userID, response["Message"].AsString());
410
411 return success;
412 }
413
414 private OSDMap FetchUserData(UUID userID)
415 {
416 NameValueCollection requestArgs = new NameValueCollection
417 {
418 { "RequestMethod", "GetUser" },
419 { "UserID", userID.ToString() }
420 };
421
422 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
423 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
424 {
425 return (OSDMap)response["User"];
426 }
427 else
428 {
429 m_log.Error("[SIMIAN PROFILES]: Failed to fetch user data for " + userID + ": " + response["Message"].AsString());
430 }
431
432 return null;
433 }
434 }
435}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
new file mode 100644
index 0000000..874f1a2
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
@@ -0,0 +1,311 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.IO;
32using System.Reflection;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Services.Interfaces;
37using log4net;
38using Mono.Addins;
39using Nini.Config;
40using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Connects user account data (creating new users, looking up existing
47 /// users) to the SimianGrid backend
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class SimianUserAccountServiceConnector : IUserAccountService, ISharedRegionModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private string m_serverUrl = String.Empty;
57 private ExpiringCache<UUID, UserAccount> m_accountCache;
58
59 #region ISharedRegionModule
60
61 public Type ReplaceableInterface { get { return null; } }
62 public void RegionLoaded(Scene scene) { }
63 public void PostInitialise() { }
64 public void Close() { }
65
66 public SimianUserAccountServiceConnector() { }
67 public string Name { get { return "SimianUserAccountServiceConnector"; } }
68 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IUserAccountService>(this); } }
69 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IUserAccountService>(this); } }
70
71 #endregion ISharedRegionModule
72
73 public SimianUserAccountServiceConnector(IConfigSource source)
74 {
75 Initialise(source);
76 }
77
78 public void Initialise(IConfigSource source)
79 {
80 if (Simian.IsSimianEnabled(source, "UserAccountServices", this.Name))
81 {
82 IConfig assetConfig = source.Configs["UserAccountService"];
83 if (assetConfig == null)
84 {
85 m_log.Error("[SIMIAN ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini");
86 throw new Exception("User account connector init error");
87 }
88
89 string serviceURI = assetConfig.GetString("UserAccountServerURI");
90 if (String.IsNullOrEmpty(serviceURI))
91 {
92 m_log.Error("[SIMIAN ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService, skipping SimianUserAccountServiceConnector");
93 throw new Exception("User account connector init error");
94 }
95
96 m_accountCache = new ExpiringCache<UUID, UserAccount>();
97 m_serverUrl = serviceURI;
98 }
99 }
100
101 public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
102 {
103 NameValueCollection requestArgs = new NameValueCollection
104 {
105 { "RequestMethod", "GetUser" },
106 { "Name", firstName + ' ' + lastName }
107 };
108
109 return GetUser(requestArgs);
110 }
111
112 public UserAccount GetUserAccount(UUID scopeID, string email)
113 {
114 NameValueCollection requestArgs = new NameValueCollection
115 {
116 { "RequestMethod", "GetUser" },
117 { "Email", email }
118 };
119
120 return GetUser(requestArgs);
121 }
122
123 public UserAccount GetUserAccount(UUID scopeID, UUID userID)
124 {
125 // Cache check
126 UserAccount account;
127 if (m_accountCache.TryGetValue(userID, out account))
128 return account;
129
130 NameValueCollection requestArgs = new NameValueCollection
131 {
132 { "RequestMethod", "GetUser" },
133 { "UserID", userID.ToString() }
134 };
135
136 return GetUser(requestArgs);
137 }
138
139 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
140 {
141 List<UserAccount> accounts = new List<UserAccount>();
142
143 m_log.DebugFormat("[SIMIAN ACCOUNT CONNECTOR]: Searching for user accounts with name query " + query);
144
145 NameValueCollection requestArgs = new NameValueCollection
146 {
147 { "RequestMethod", "GetUsers" },
148 { "NameQuery", query }
149 };
150
151 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
152 if (response["Success"].AsBoolean())
153 {
154 OSDArray array = response["Users"] as OSDArray;
155 if (array != null && array.Count > 0)
156 {
157 for (int i = 0; i < array.Count; i++)
158 {
159 UserAccount account = ResponseToUserAccount(array[i] as OSDMap);
160 if (account != null)
161 accounts.Add(account);
162 }
163 }
164 else
165 {
166 m_log.Warn("[SIMIAN ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
167 }
168 }
169 else
170 {
171 m_log.Warn("[SIMIAN ACCOUNT CONNECTOR]: Failed to search for account data by name " + query);
172 }
173
174 return accounts;
175 }
176
177 public bool StoreUserAccount(UserAccount data)
178 {
179 m_log.InfoFormat("[SIMIAN ACCOUNT CONNECTOR]: Storing user account for " + data.Name);
180
181 NameValueCollection requestArgs = new NameValueCollection
182 {
183 { "RequestMethod", "AddUser" },
184 { "UserID", data.PrincipalID.ToString() },
185 { "Name", data.Name },
186 { "Email", data.Email },
187 { "AccessLevel", data.UserLevel.ToString() }
188 };
189
190 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
191
192 if (response["Success"].AsBoolean())
193 {
194 m_log.InfoFormat("[SIMIAN ACCOUNT CONNECTOR]: Storing user account data for " + data.Name);
195
196 requestArgs = new NameValueCollection
197 {
198 { "RequestMethod", "AddUserData" },
199 { "UserID", data.PrincipalID.ToString() },
200 { "CreationDate", data.Created.ToString() },
201 { "UserFlags", data.UserFlags.ToString() },
202 { "UserTitle", data.UserTitle }
203 };
204
205 response = WebUtil.PostToService(m_serverUrl, requestArgs);
206 bool success = response["Success"].AsBoolean();
207
208 if (success)
209 {
210 // Cache the user account info
211 m_accountCache.AddOrUpdate(data.PrincipalID, data, DateTime.Now + TimeSpan.FromMinutes(2.0d));
212 }
213 else
214 {
215 m_log.Warn("[SIMIAN ACCOUNT CONNECTOR]: Failed to store user account data for " + data.Name + ": " + response["Message"].AsString());
216 }
217
218 return success;
219 }
220 else
221 {
222 m_log.Warn("[SIMIAN ACCOUNT CONNECTOR]: Failed to store user account for " + data.Name + ": " + response["Message"].AsString());
223 }
224
225 return false;
226 }
227
228 /// <summary>
229 /// Helper method for the various ways of retrieving a user account
230 /// </summary>
231 /// <param name="requestArgs">Service query parameters</param>
232 /// <returns>A UserAccount object on success, null on failure</returns>
233 private UserAccount GetUser(NameValueCollection requestArgs)
234 {
235 string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)";
236 m_log.DebugFormat("[SIMIAN ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue);
237
238 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
239 if (response["Success"].AsBoolean())
240 {
241 OSDMap user = response["User"] as OSDMap;
242 if (user != null)
243 return ResponseToUserAccount(user);
244 else
245 m_log.Warn("[SIMIAN ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
246 }
247 else
248 {
249 m_log.Warn("[SIMIAN ACCOUNT CONNECTOR]: Failed to lookup user account with query: " + lookupValue);
250 }
251
252 return null;
253 }
254
255 /// <summary>
256 /// Convert a User object in LLSD format to a UserAccount
257 /// </summary>
258 /// <param name="response">LLSD containing user account data</param>
259 /// <returns>A UserAccount object on success, null on failure</returns>
260 private UserAccount ResponseToUserAccount(OSDMap response)
261 {
262 if (response == null)
263 return null;
264
265 UserAccount account = new UserAccount();
266 account.PrincipalID = response["UserID"].AsUUID();
267 account.Created = response["CreationDate"].AsInteger();
268 account.Email = response["Email"].AsString();
269 account.ServiceURLs = new Dictionary<string, object>(0);
270 account.UserFlags = response["UserFlags"].AsInteger();
271 account.UserLevel = response["AccessLevel"].AsInteger();
272 account.UserTitle = response["UserTitle"].AsString();
273 GetFirstLastName(response["Name"].AsString(), out account.FirstName, out account.LastName);
274
275 // Cache the user account info
276 m_accountCache.AddOrUpdate(account.PrincipalID, account, DateTime.Now + TimeSpan.FromMinutes(2.0d));
277
278 return account;
279 }
280
281 /// <summary>
282 /// Convert a name with a single space in it to a first and last name
283 /// </summary>
284 /// <param name="name">A full name such as "John Doe"</param>
285 /// <param name="firstName">First name</param>
286 /// <param name="lastName">Last name (surname)</param>
287 private static void GetFirstLastName(string name, out string firstName, out string lastName)
288 {
289 if (String.IsNullOrEmpty(name))
290 {
291 firstName = String.Empty;
292 lastName = String.Empty;
293 }
294 else
295 {
296 string[] names = name.Split(' ');
297
298 if (names.Length == 2)
299 {
300 firstName = names[0];
301 lastName = names[1];
302 }
303 else
304 {
305 firstName = String.Empty;
306 lastName = name;
307 }
308 }
309 }
310 }
311}
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
new file mode 100644
index 0000000..8e0063b
--- /dev/null
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -0,0 +1,613 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34
35using OpenSim.Framework;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using log4net;
42using Nini.Config;
43
44namespace OpenSim.Services.Connectors.Simulation
45{
46 public class SimulationServiceConnector : ISimulationService
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //private GridRegion m_Region;
51
52 public SimulationServiceConnector()
53 {
54 }
55
56 public SimulationServiceConnector(IConfigSource config)
57 {
58 //m_Region = region;
59 }
60
61 public IScene GetScene(ulong regionHandle)
62 {
63 return null;
64 }
65
66 public ISimulationService GetInnerService()
67 {
68 return null;
69 }
70
71 #region Agents
72
73 protected virtual string AgentPath()
74 {
75 return "/agent/";
76 }
77
78 public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason)
79 {
80 reason = String.Empty;
81
82 if (destination == null)
83 {
84 reason = "Destination is null";
85 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null");
86 return false;
87 }
88
89 // Eventually, we want to use a caps url instead of the agentID
90 string uri = string.Empty;
91 try
92 {
93 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + aCircuit.AgentID + "/";
94 }
95 catch (Exception e)
96 {
97 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent create. Reason: " + e.Message);
98 reason = e.Message;
99 return false;
100 }
101
102 //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
103
104 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
105 AgentCreateRequest.Method = "POST";
106 AgentCreateRequest.ContentType = "application/json";
107 AgentCreateRequest.Timeout = 10000;
108 //AgentCreateRequest.KeepAlive = false;
109 //AgentCreateRequest.Headers.Add("Authorization", authKey);
110
111 // Fill it in
112 OSDMap args = PackCreateAgentArguments(aCircuit, destination, flags);
113 if (args == null)
114 return false;
115
116 string strBuffer = "";
117 byte[] buffer = new byte[1];
118 try
119 {
120 strBuffer = OSDParser.SerializeJsonString(args);
121 Encoding str = Util.UTF8;
122 buffer = str.GetBytes(strBuffer);
123
124 }
125 catch (Exception e)
126 {
127 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
128 // ignore. buffer will be empty, caller should check.
129 }
130
131 Stream os = null;
132 try
133 { // send the Post
134 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
135 os = AgentCreateRequest.GetRequestStream();
136 os.Write(buffer, 0, strBuffer.Length); //Send it
137 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
138 uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
139 }
140 //catch (WebException ex)
141 catch
142 {
143 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
144 reason = "cannot contact remote region";
145 return false;
146 }
147 finally
148 {
149 if (os != null)
150 os.Close();
151 }
152
153 // Let's wait for the response
154 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
155
156 WebResponse webResponse = null;
157 StreamReader sr = null;
158 try
159 {
160 webResponse = AgentCreateRequest.GetResponse();
161 if (webResponse == null)
162 {
163 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on DoCreateChildAgentCall post");
164 }
165 else
166 {
167
168 sr = new StreamReader(webResponse.GetResponseStream());
169 string response = sr.ReadToEnd().Trim();
170 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
171
172 if (!String.IsNullOrEmpty(response))
173 {
174 try
175 {
176 // we assume we got an OSDMap back
177 OSDMap r = Util.GetOSDMap(response);
178 bool success = r["success"].AsBoolean();
179 reason = r["reason"].AsString();
180 return success;
181 }
182 catch (NullReferenceException e)
183 {
184 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
185
186 // check for old style response
187 if (response.ToLower().StartsWith("true"))
188 return true;
189
190 return false;
191 }
192 }
193 }
194 }
195 catch (WebException ex)
196 {
197 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
198 reason = "Destination did not reply";
199 return false;
200 }
201 finally
202 {
203 if (sr != null)
204 sr.Close();
205 }
206
207 return true;
208 }
209
210 protected virtual OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion destination, uint flags)
211 {
212 OSDMap args = null;
213 try
214 {
215 args = aCircuit.PackAgentCircuitData();
216 }
217 catch (Exception e)
218 {
219 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
220 return null;
221 }
222 // Add the input arguments
223 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
224 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
225 args["destination_name"] = OSD.FromString(destination.RegionName);
226 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
227 args["teleport_flags"] = OSD.FromString(flags.ToString());
228
229 return args;
230 }
231
232 public bool UpdateAgent(GridRegion destination, AgentData data)
233 {
234 return UpdateAgent(destination, (IAgentData)data);
235 }
236
237 public bool UpdateAgent(GridRegion destination, AgentPosition data)
238 {
239 return UpdateAgent(destination, (IAgentData)data);
240 }
241
242 private bool UpdateAgent(GridRegion destination, IAgentData cAgentData)
243 {
244 // Eventually, we want to use a caps url instead of the agentID
245 string uri = string.Empty;
246 try
247 {
248 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + cAgentData.AgentID + "/";
249 }
250 catch (Exception e)
251 {
252 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent update. Reason: " + e.Message);
253 return false;
254 }
255 //Console.WriteLine(" >>> DoAgentUpdateCall <<< " + uri);
256
257 HttpWebRequest ChildUpdateRequest = (HttpWebRequest)WebRequest.Create(uri);
258 ChildUpdateRequest.Method = "PUT";
259 ChildUpdateRequest.ContentType = "application/json";
260 ChildUpdateRequest.Timeout = 10000;
261 //ChildUpdateRequest.KeepAlive = false;
262
263 // Fill it in
264 OSDMap args = null;
265 try
266 {
267 args = cAgentData.Pack();
268 }
269 catch (Exception e)
270 {
271 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackUpdateMessage failed with exception: " + e.Message);
272 }
273 // Add the input arguments
274 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
275 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
276 args["destination_name"] = OSD.FromString(destination.RegionName);
277 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
278
279 string strBuffer = "";
280 byte[] buffer = new byte[1];
281 try
282 {
283 strBuffer = OSDParser.SerializeJsonString(args);
284 Encoding str = Util.UTF8;
285 buffer = str.GetBytes(strBuffer);
286
287 }
288 catch (Exception e)
289 {
290 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of ChildUpdate: {0}", e.Message);
291 // ignore. buffer will be empty, caller should check.
292 }
293
294 Stream os = null;
295 try
296 { // send the Post
297 ChildUpdateRequest.ContentLength = buffer.Length; //Count bytes to send
298 os = ChildUpdateRequest.GetRequestStream();
299 os.Write(buffer, 0, strBuffer.Length); //Send it
300 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted AgentUpdate request to remote sim {0}", uri);
301 }
302 catch (WebException ex)
303 //catch
304 {
305 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on AgentUpdate {0}", ex.Message);
306
307 return false;
308 }
309 finally
310 {
311 if (os != null)
312 os.Close();
313 }
314
315 // Let's wait for the response
316 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after ChildAgentUpdate");
317
318 WebResponse webResponse = null;
319 StreamReader sr = null;
320 try
321 {
322 webResponse = ChildUpdateRequest.GetResponse();
323 if (webResponse == null)
324 {
325 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on ChilAgentUpdate post");
326 }
327
328 sr = new StreamReader(webResponse.GetResponseStream());
329 //reply = sr.ReadToEnd().Trim();
330 sr.ReadToEnd().Trim();
331 sr.Close();
332 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
333
334 }
335 catch (WebException ex)
336 {
337 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of ChilAgentUpdate {0}", ex.Message);
338 // ignore, really
339 }
340 finally
341 {
342 if (sr != null)
343 sr.Close();
344 }
345
346 return true;
347 }
348
349 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
350 {
351 agent = null;
352 // Eventually, we want to use a caps url instead of the agentID
353 string uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
354 //Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri);
355
356 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
357 request.Method = "GET";
358 request.Timeout = 10000;
359 //request.Headers.Add("authorization", ""); // coming soon
360
361 HttpWebResponse webResponse = null;
362 string reply = string.Empty;
363 StreamReader sr = null;
364 try
365 {
366 webResponse = (HttpWebResponse)request.GetResponse();
367 if (webResponse == null)
368 {
369 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent get ");
370 }
371
372 sr = new StreamReader(webResponse.GetResponseStream());
373 reply = sr.ReadToEnd().Trim();
374
375 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was " + reply);
376
377 }
378 catch (WebException ex)
379 {
380 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent get {0}", ex.Message);
381 // ignore, really
382 return false;
383 }
384 finally
385 {
386 if (sr != null)
387 sr.Close();
388 }
389
390 if (webResponse.StatusCode == HttpStatusCode.OK)
391 {
392 // we know it's jason
393 OSDMap args = Util.GetOSDMap(reply);
394 if (args == null)
395 {
396 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: Error getting OSDMap from reply");
397 return false;
398 }
399
400 agent = new CompleteAgentData();
401 agent.Unpack(args);
402 return true;
403 }
404
405 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: DoRetrieveRootAgentCall returned status " + webResponse.StatusCode);
406 return false;
407 }
408
409 public bool ReleaseAgent(UUID origin, UUID id, string uri)
410 {
411 WebRequest request = WebRequest.Create(uri);
412 request.Method = "DELETE";
413 request.Timeout = 10000;
414
415 StreamReader sr = null;
416 try
417 {
418 WebResponse webResponse = request.GetResponse();
419 if (webResponse == null)
420 {
421 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on ReleaseAgent");
422 }
423
424 sr = new StreamReader(webResponse.GetResponseStream());
425 //reply = sr.ReadToEnd().Trim();
426 sr.ReadToEnd().Trim();
427 sr.Close();
428 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
429
430 }
431 catch (WebException ex)
432 {
433 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of ReleaseAgent {0}", ex.Message);
434 return false;
435 }
436 finally
437 {
438 if (sr != null)
439 sr.Close();
440 }
441
442 return true;
443 }
444
445 private bool CloseAgent(GridRegion destination, UUID id, bool ChildOnly)
446 {
447 string uri = string.Empty;
448 try
449 {
450 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
451 }
452 catch (Exception e)
453 {
454 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent close. Reason: " + e.Message);
455 return false;
456 }
457
458 //Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
459
460 WebRequest request = WebRequest.Create(uri);
461 request.Method = "DELETE";
462 if (ChildOnly)
463 request.Method += "CHILD";
464 request.Timeout = 10000;
465
466 StreamReader sr = null;
467 try
468 {
469 WebResponse webResponse = request.GetResponse();
470 if (webResponse == null)
471 {
472 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent delete ");
473 }
474
475 sr = new StreamReader(webResponse.GetResponseStream());
476 //reply = sr.ReadToEnd().Trim();
477 sr.ReadToEnd().Trim();
478 sr.Close();
479 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
480
481 }
482 catch (WebException ex)
483 {
484 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent delete {0}", ex.Message);
485 return false;
486 }
487 finally
488 {
489 if (sr != null)
490 sr.Close();
491 }
492
493 return true;
494 }
495
496 public bool CloseChildAgent(GridRegion destination, UUID id)
497 {
498 return CloseAgent(destination, id, true);
499 }
500
501 public bool CloseAgent(GridRegion destination, UUID id)
502 {
503 return CloseAgent(destination, id, false);
504 }
505
506 #endregion Agents
507
508 #region Objects
509
510 protected virtual string ObjectPath()
511 {
512 return "/object/";
513 }
514
515 public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
516 {
517 string uri
518 = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + ObjectPath() + sog.UUID + "/";
519 //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri);
520
521 WebRequest ObjectCreateRequest = WebRequest.Create(uri);
522 ObjectCreateRequest.Method = "POST";
523 ObjectCreateRequest.ContentType = "application/json";
524 ObjectCreateRequest.Timeout = 10000;
525
526 OSDMap args = new OSDMap(2);
527 args["sog"] = OSD.FromString(sog.ToXml2());
528 args["extra"] = OSD.FromString(sog.ExtraToXmlString());
529 string state = sog.GetStateSnapshot();
530 if (state.Length > 0)
531 args["state"] = OSD.FromString(state);
532 // Add the input general arguments
533 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
534 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
535 args["destination_name"] = OSD.FromString(destination.RegionName);
536 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
537
538 string strBuffer = "";
539 byte[] buffer = new byte[1];
540 try
541 {
542 strBuffer = OSDParser.SerializeJsonString(args);
543 Encoding str = Util.UTF8;
544 buffer = str.GetBytes(strBuffer);
545
546 }
547 catch (Exception e)
548 {
549 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of CreateObject: {0}", e.Message);
550 // ignore. buffer will be empty, caller should check.
551 }
552
553 Stream os = null;
554 try
555 { // send the Post
556 ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
557 os = ObjectCreateRequest.GetRequestStream();
558 os.Write(buffer, 0, strBuffer.Length); //Send it
559 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateObject request to remote sim {0}", uri);
560 }
561 catch (WebException ex)
562 {
563 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on CreateObject {0}", ex.Message);
564 return false;
565 }
566 finally
567 {
568 if (os != null)
569 os.Close();
570 }
571
572 // Let's wait for the response
573 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
574
575 StreamReader sr = null;
576 try
577 {
578 WebResponse webResponse = ObjectCreateRequest.GetResponse();
579 if (webResponse == null)
580 {
581 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on CreateObject post");
582 return false;
583 }
584
585 sr = new StreamReader(webResponse.GetResponseStream());
586 //reply = sr.ReadToEnd().Trim();
587 sr.ReadToEnd().Trim();
588 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", reply);
589
590 }
591 catch (WebException ex)
592 {
593 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of CreateObject {0}", ex.Message);
594 return false;
595 }
596 finally
597 {
598 if (sr != null)
599 sr.Close();
600 }
601
602 return true;
603 }
604
605 public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
606 {
607 // TODO, not that urgent
608 return false;
609 }
610
611 #endregion Objects
612 }
613}
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
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using OpenMetaverse;
39
40namespace 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..38c191a
--- /dev/null
+++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
@@ -0,0 +1,278 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Server.Base;
38using OpenSim.Services.Interfaces;
39using OpenMetaverse;
40
41namespace 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 virtual 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 virtual 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 virtual UserAccount GetUserAccount(UUID scopeID, UUID userID)
115 {
116 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccount {0}", userID);
117 Dictionary<string, object> sendData = new Dictionary<string, object>();
118 //sendData["SCOPEID"] = scopeID.ToString();
119 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
120 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
121 sendData["METHOD"] = "getaccount";
122
123 sendData["ScopeID"] = scopeID;
124 sendData["UserID"] = userID.ToString();
125
126 return SendAndGetReply(sendData);
127 }
128
129 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
130 {
131 Dictionary<string, object> sendData = new Dictionary<string, object>();
132 //sendData["SCOPEID"] = scopeID.ToString();
133 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
134 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
135 sendData["METHOD"] = "getaccounts";
136
137 sendData["ScopeID"] = scopeID.ToString();
138 sendData["query"] = query;
139
140 string reply = string.Empty;
141 string reqString = ServerUtils.BuildQueryString(sendData);
142 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
143 try
144 {
145 reply = SynchronousRestFormsRequester.MakeRequest("POST",
146 m_ServerURI + "/accounts",
147 reqString);
148 if (reply == null || (reply != null && reply == string.Empty))
149 {
150 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply");
151 return null;
152 }
153 }
154 catch (Exception e)
155 {
156 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting accounts server: {0}", e.Message);
157 }
158
159 List<UserAccount> accounts = new List<UserAccount>();
160
161 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
162
163 if (replyData != null)
164 {
165 if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null")
166 {
167 return accounts;
168 }
169
170 Dictionary<string, object>.ValueCollection accountList = replyData.Values;
171 //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
172 foreach (object acc in accountList)
173 {
174 if (acc is Dictionary<string, object>)
175 {
176 UserAccount pinfo = new UserAccount((Dictionary<string, object>)acc);
177 accounts.Add(pinfo);
178 }
179 else
180 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received invalid response type {0}",
181 acc.GetType());
182 }
183 }
184 else
185 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccounts received null response");
186
187 return accounts;
188 }
189
190 public virtual bool StoreUserAccount(UserAccount data)
191 {
192 Dictionary<string, object> sendData = new Dictionary<string, object>();
193 //sendData["SCOPEID"] = scopeID.ToString();
194 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
195 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
196 sendData["METHOD"] = "setaccount";
197
198 Dictionary<string, object> structData = data.ToKeyValuePairs();
199
200 foreach (KeyValuePair<string,object> kvp in structData)
201 sendData[kvp.Key] = kvp.Value.ToString();
202
203 return SendAndGetBoolReply(sendData);
204 }
205
206 private UserAccount SendAndGetReply(Dictionary<string, object> sendData)
207 {
208 string reply = string.Empty;
209 string reqString = ServerUtils.BuildQueryString(sendData);
210 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
211 try
212 {
213 reply = SynchronousRestFormsRequester.MakeRequest("POST",
214 m_ServerURI + "/accounts",
215 reqString);
216 if (reply == null || (reply != null && reply == string.Empty))
217 {
218 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply");
219 return null;
220 }
221 }
222 catch (Exception e)
223 {
224 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user account server: {0}", e.Message);
225 }
226
227 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
228 UserAccount account = null;
229
230 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
231 {
232 if (replyData["result"] is Dictionary<string, object>)
233 {
234 account = new UserAccount((Dictionary<string, object>)replyData["result"]);
235 }
236 }
237
238 return account;
239
240 }
241
242 private bool SendAndGetBoolReply(Dictionary<string, object> sendData)
243 {
244 string reqString = ServerUtils.BuildQueryString(sendData);
245 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
246 try
247 {
248 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
249 m_ServerURI + "/accounts",
250 reqString);
251 if (reply != string.Empty)
252 {
253 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
254
255 if (replyData.ContainsKey("result"))
256 {
257 if (replyData["result"].ToString().ToLower() == "success")
258 return true;
259 else
260 return false;
261 }
262 else
263 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount reply data does not contain result field");
264
265 }
266 else
267 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount received empty reply");
268 }
269 catch (Exception e)
270 {
271 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Exception when contacting user account server: {0}", e.Message);
272 }
273
274 return false;
275 }
276
277 }
278}
diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs
new file mode 100644
index 0000000..3c64ecc
--- /dev/null
+++ b/OpenSim/Services/Friends/FriendsService.cs
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29using OpenSim.Framework;
30using System;
31using System.Collections.Generic;
32using OpenSim.Services.Interfaces;
33using OpenSim.Data;
34using Nini.Config;
35using log4net;
36using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
37
38namespace OpenSim.Services.Friends
39{
40 public class FriendsService : FriendsServiceBase, IFriendsService
41 {
42 public FriendsService(IConfigSource config) : base(config)
43 {
44 }
45
46 public FriendInfo[] GetFriends(UUID PrincipalID)
47 {
48 FriendsData[] data = m_Database.GetFriends(PrincipalID);
49
50 List<FriendInfo> info = new List<FriendInfo>();
51
52 foreach (FriendsData d in data)
53 {
54 FriendInfo i = new FriendInfo();
55
56 i.PrincipalID = d.PrincipalID;
57 i.Friend = d.Friend;
58 i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
59 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
60
61 info.Add(i);
62 }
63
64 return info.ToArray();
65 }
66
67 public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
68 {
69 FriendsData d = new FriendsData();
70
71 d.PrincipalID = PrincipalID;
72 d.Friend = Friend;
73 d.Data = new Dictionary<string, string>();
74 d.Data["Flags"] = flags.ToString();
75
76 return m_Database.Store(d);
77 }
78
79 public bool Delete(UUID PrincipalID, string Friend)
80 {
81 return m_Database.Delete(PrincipalID, Friend);
82 }
83
84 }
85}
diff --git a/OpenSim/Services/Friends/FriendsServiceBase.cs b/OpenSim/Services/Friends/FriendsServiceBase.cs
new file mode 100644
index 0000000..6ab0bff
--- /dev/null
+++ b/OpenSim/Services/Friends/FriendsServiceBase.cs
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using log4net;
31using Nini.Config;
32using OpenSim.Framework;
33using OpenSim.Data;
34using OpenSim.Services.Interfaces;
35using OpenSim.Services.Base;
36
37namespace OpenSim.Services.Friends
38{
39 public class FriendsServiceBase : ServiceBase
40 {
41 protected IFriendsData m_Database = null;
42
43 public FriendsServiceBase(IConfigSource config) : base(config)
44 {
45 string dllName = String.Empty;
46 string connString = String.Empty;
47
48 //
49 // Try reading the [FriendsService] section first, if it exists
50 //
51 IConfig friendsConfig = config.Configs["FriendsService"];
52 if (friendsConfig != null)
53 {
54 dllName = friendsConfig.GetString("StorageProvider", dllName);
55 connString = friendsConfig.GetString("ConnectionString", connString);
56 }
57
58 //
59 // Try reading the [DatabaseService] section, if it exists
60 //
61 IConfig dbConfig = config.Configs["DatabaseService"];
62 if (dbConfig != null)
63 {
64 if (dllName == String.Empty)
65 dllName = dbConfig.GetString("StorageProvider", String.Empty);
66 if (connString == String.Empty)
67 connString = dbConfig.GetString("ConnectionString", String.Empty);
68 }
69
70 //
71 // We tried, but this doesn't exist. We can't proceed.
72 //
73 if (String.Empty.Equals(dllName))
74 throw new Exception("No StorageProvider configured");
75
76 string realm = "Friends";
77 if (friendsConfig != null)
78 realm = friendsConfig.GetString("Realm", realm);
79
80 m_Database = LoadPlugin<IFriendsData>(dllName, new Object[] { connString, realm });
81 if (m_Database == null)
82 {
83 throw new Exception(
84 string.Format(
85 "Could not find a storage interface {0} in the given StorageProvider {1}", "IFriendsData", dllName));
86 }
87 }
88 }
89}
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 7749c37..7c98642 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -34,6 +34,7 @@ using log4net;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
36using OpenSim.Data; 36using OpenSim.Data;
37using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion; 39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenMetaverse; 40using OpenMetaverse;
@@ -46,17 +47,58 @@ namespace OpenSim.Services.GridService
46 LogManager.GetLogger( 47 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
48 49
50 private bool m_DeleteOnUnregister = true;
51 private static GridService m_RootInstance = null;
52 protected IConfigSource m_config;
53 protected HypergridLinker m_HypergridLinker;
54
55 protected IAuthenticationService m_AuthenticationService = null;
49 protected bool m_AllowDuplicateNames = false; 56 protected bool m_AllowDuplicateNames = false;
57 protected bool m_AllowHypergridMapSearch = false;
50 58
51 public GridService(IConfigSource config) 59 public GridService(IConfigSource config)
52 : base(config) 60 : base(config)
53 { 61 {
54 m_log.DebugFormat("[GRID SERVICE]: Starting..."); 62 m_log.DebugFormat("[GRID SERVICE]: Starting...");
55 63
64 m_config = config;
56 IConfig gridConfig = config.Configs["GridService"]; 65 IConfig gridConfig = config.Configs["GridService"];
57 if (gridConfig != null) 66 if (gridConfig != null)
58 { 67 {
68 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true);
69
70 string authService = gridConfig.GetString("AuthenticationService", String.Empty);
71
72 if (authService != String.Empty)
73 {
74 Object[] args = new Object[] { config };
75 m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
76 }
59 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); 77 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
78 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch);
79 }
80
81 if (m_RootInstance == null)
82 {
83 m_RootInstance = this;
84
85 if (MainConsole.Instance != null)
86 {
87 MainConsole.Instance.Commands.AddCommand("grid", true,
88 "show region",
89 "show region <Region name>",
90 "Show details on a region",
91 String.Empty,
92 HandleShowRegion);
93
94 MainConsole.Instance.Commands.AddCommand("grid", true,
95 "set region flags",
96 "set region flags <Region name> <flags>",
97 "Set database flags for region",
98 String.Empty,
99 HandleSetFlags);
100 }
101 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database);
60 } 102 }
61 } 103 }
62 104
@@ -64,9 +106,46 @@ namespace OpenSim.Services.GridService
64 106
65 public string RegisterRegion(UUID scopeID, GridRegion regionInfos) 107 public string RegisterRegion(UUID scopeID, GridRegion regionInfos)
66 { 108 {
109 IConfig gridConfig = m_config.Configs["GridService"];
67 // This needs better sanity testing. What if regionInfo is registering in 110 // This needs better sanity testing. What if regionInfo is registering in
68 // overlapping coords? 111 // overlapping coords?
69 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 112 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
113 if (region != null)
114 {
115 // There is a preexisting record
116 //
117 // Get it's flags
118 //
119 OpenSim.Data.RegionFlags rflags = (OpenSim.Data.RegionFlags)Convert.ToInt32(region.Data["flags"]);
120
121 // Is this a reservation?
122 //
123 if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0)
124 {
125 // Regions reserved for the null key cannot be taken.
126 if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString())
127 return "Region location us reserved";
128
129 // Treat it as an auth request
130 //
131 // NOTE: Fudging the flags value here, so these flags
132 // should not be used elsewhere. Don't optimize
133 // this with the later retrieval of the same flags!
134 rflags |= OpenSim.Data.RegionFlags.Authenticate;
135 }
136
137 if ((rflags & OpenSim.Data.RegionFlags.Authenticate) != 0)
138 {
139 // Can we authenticate at all?
140 //
141 if (m_AuthenticationService == null)
142 return "No authentication possible";
143
144 if (!m_AuthenticationService.Verify(new UUID(region.Data["PrincipalID"].ToString()), regionInfos.Token, 30))
145 return "Bad authentication";
146 }
147 }
148
70 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 149 if ((region != null) && (region.RegionID != regionInfos.RegionID))
71 { 150 {
72 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", 151 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
@@ -76,6 +155,9 @@ namespace OpenSim.Services.GridService
76 if ((region != null) && (region.RegionID == regionInfos.RegionID) && 155 if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
77 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY))) 156 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
78 { 157 {
158 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
159 return "Can't move this region";
160
79 // Region reregistering in other coordinates. Delete the old entry 161 // Region reregistering in other coordinates. Delete the old entry
80 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.", 162 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
81 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); 163 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
@@ -110,8 +192,37 @@ namespace OpenSim.Services.GridService
110 // Everything is ok, let's register 192 // Everything is ok, let's register
111 RegionData rdata = RegionInfo2RegionData(regionInfos); 193 RegionData rdata = RegionInfo2RegionData(regionInfos);
112 rdata.ScopeID = scopeID; 194 rdata.ScopeID = scopeID;
195
196 if (region != null)
197 {
198 int oldFlags = Convert.ToInt32(region.Data["flags"]);
199 if ((oldFlags & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
200 return "Region locked out";
201
202 oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation;
203
204 rdata.Data["flags"] = oldFlags.ToString(); // Preserve flags
205 }
206 else
207 {
208 rdata.Data["flags"] = "0";
209 if ((gridConfig != null) && rdata.RegionName != string.Empty)
210 {
211 int newFlags = 0;
212 string regionName = rdata.RegionName.Trim().Replace(' ', '_');
213 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + regionName, String.Empty));
214 newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + rdata.RegionID.ToString(), String.Empty));
215 rdata.Data["flags"] = newFlags.ToString();
216 }
217 }
218
219 int flags = Convert.ToInt32(rdata.Data["flags"]);
220 flags |= (int)OpenSim.Data.RegionFlags.RegionOnline;
221 rdata.Data["flags"] = flags.ToString();
222
113 try 223 try
114 { 224 {
225 rdata.Data["last_seen"] = Util.UnixTimeSinceEpoch();
115 m_Database.Store(rdata); 226 m_Database.Store(rdata);
116 } 227 }
117 catch (Exception e) 228 catch (Exception e)
@@ -128,6 +239,30 @@ namespace OpenSim.Services.GridService
128 public bool DeregisterRegion(UUID regionID) 239 public bool DeregisterRegion(UUID regionID)
129 { 240 {
130 m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID); 241 m_log.DebugFormat("[GRID SERVICE]: Region {0} deregistered", regionID);
242 RegionData region = m_Database.Get(regionID, UUID.Zero);
243 if (region == null)
244 return false;
245
246 int flags = Convert.ToInt32(region.Data["flags"]);
247
248 if (!m_DeleteOnUnregister || (flags & (int)OpenSim.Data.RegionFlags.Persistent) != 0)
249 {
250 flags &= ~(int)OpenSim.Data.RegionFlags.RegionOnline;
251 region.Data["flags"] = flags.ToString();
252 region.Data["last_seen"] = Util.UnixTimeSinceEpoch();
253 try
254 {
255 m_Database.Store(region);
256 }
257 catch (Exception e)
258 {
259 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
260 }
261
262 return true;
263
264 }
265
131 return m_Database.Delete(regionID); 266 return m_Database.Delete(regionID);
132 } 267 }
133 268
@@ -180,6 +315,8 @@ namespace OpenSim.Services.GridService
180 315
181 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber) 316 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
182 { 317 {
318 m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);
319
183 List<RegionData> rdatas = m_Database.Get("%" + name + "%", scopeID); 320 List<RegionData> rdatas = m_Database.Get("%" + name + "%", scopeID);
184 321
185 int count = 0; 322 int count = 0;
@@ -187,6 +324,7 @@ namespace OpenSim.Services.GridService
187 324
188 if (rdatas != null) 325 if (rdatas != null)
189 { 326 {
327 m_log.DebugFormat("[GRID SERVICE]: Found {0} regions", rdatas.Count);
190 foreach (RegionData rdata in rdatas) 328 foreach (RegionData rdata in rdatas)
191 { 329 {
192 if (count++ < maxNumber) 330 if (count++ < maxNumber)
@@ -194,6 +332,13 @@ namespace OpenSim.Services.GridService
194 } 332 }
195 } 333 }
196 334
335 if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0)) && name.Contains("."))
336 {
337 GridRegion r = m_HypergridLinker.LinkRegion(scopeID, name);
338 if (r != null)
339 rinfos.Add(r);
340 }
341
197 return rinfos; 342 return rinfos;
198 } 343 }
199 344
@@ -216,7 +361,7 @@ namespace OpenSim.Services.GridService
216 361
217 #region Data structure conversions 362 #region Data structure conversions
218 363
219 protected RegionData RegionInfo2RegionData(GridRegion rinfo) 364 public RegionData RegionInfo2RegionData(GridRegion rinfo)
220 { 365 {
221 RegionData rdata = new RegionData(); 366 RegionData rdata = new RegionData();
222 rdata.posX = (int)rinfo.RegionLocX; 367 rdata.posX = (int)rinfo.RegionLocX;
@@ -229,7 +374,7 @@ namespace OpenSim.Services.GridService
229 return rdata; 374 return rdata;
230 } 375 }
231 376
232 protected GridRegion RegionData2RegionInfo(RegionData rdata) 377 public GridRegion RegionData2RegionInfo(RegionData rdata)
233 { 378 {
234 GridRegion rinfo = new GridRegion(rdata.Data); 379 GridRegion rinfo = new GridRegion(rdata.Data);
235 rinfo.RegionLocX = rdata.posX; 380 rinfo.RegionLocX = rdata.posX;
@@ -243,5 +388,143 @@ namespace OpenSim.Services.GridService
243 388
244 #endregion 389 #endregion
245 390
391 public List<GridRegion> GetDefaultRegions(UUID scopeID)
392 {
393 List<GridRegion> ret = new List<GridRegion>();
394
395 List<RegionData> regions = m_Database.GetDefaultRegions(scopeID);
396
397 foreach (RegionData r in regions)
398 {
399 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
400 ret.Add(RegionData2RegionInfo(r));
401 }
402
403 m_log.DebugFormat("[GRID SERVICE]: GetDefaultRegions returning {0} regions", ret.Count);
404 return ret;
405 }
406
407 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
408 {
409 List<GridRegion> ret = new List<GridRegion>();
410
411 List<RegionData> regions = m_Database.GetFallbackRegions(scopeID, x, y);
412
413 foreach (RegionData r in regions)
414 {
415 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
416 ret.Add(RegionData2RegionInfo(r));
417 }
418
419 m_log.DebugFormat("[GRID SERVICE]: Fallback returned {0} regions", ret.Count);
420 return ret;
421 }
422
423 public int GetRegionFlags(UUID scopeID, UUID regionID)
424 {
425 RegionData region = m_Database.Get(regionID, scopeID);
426
427 if (region != null)
428 {
429 int flags = Convert.ToInt32(region.Data["flags"]);
430 //m_log.DebugFormat("[GRID SERVICE]: Request for flags of {0}: {1}", regionID, flags);
431 return flags;
432 }
433 else
434 return -1;
435 }
436
437 private void HandleShowRegion(string module, string[] cmd)
438 {
439 if (cmd.Length != 3)
440 {
441 MainConsole.Instance.Output("Syntax: show region <region name>");
442 return;
443 }
444 List<RegionData> regions = m_Database.Get(cmd[2], UUID.Zero);
445 if (regions == null || regions.Count < 1)
446 {
447 MainConsole.Instance.Output("Region not found");
448 return;
449 }
450
451 MainConsole.Instance.Output("Region Name Region UUID");
452 MainConsole.Instance.Output("Location URI");
453 MainConsole.Instance.Output("Owner ID Flags");
454 MainConsole.Instance.Output("-------------------------------------------------------------------------------");
455 foreach (RegionData r in regions)
456 {
457 OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]);
458 MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n",
459 r.RegionName, r.RegionID,
460 String.Format("{0},{1}", r.posX, r.posY), "http://" + r.Data["serverIP"].ToString() + ":" + r.Data["serverPort"].ToString(),
461 r.Data["owner_uuid"].ToString(), flags.ToString()));
462 }
463 return;
464 }
465
466 private int ParseFlags(int prev, string flags)
467 {
468 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)prev;
469
470 string[] parts = flags.Split(new char[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
471
472 foreach (string p in parts)
473 {
474 int val;
475
476 try
477 {
478 if (p.StartsWith("+"))
479 {
480 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
481 f |= (OpenSim.Data.RegionFlags)val;
482 }
483 else if (p.StartsWith("-"))
484 {
485 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
486 f &= ~(OpenSim.Data.RegionFlags)val;
487 }
488 else
489 {
490 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p);
491 f |= (OpenSim.Data.RegionFlags)val;
492 }
493 }
494 catch (Exception)
495 {
496 MainConsole.Instance.Output("Error in flag specification: " + p);
497 }
498 }
499
500 return (int)f;
501 }
502
503 private void HandleSetFlags(string module, string[] cmd)
504 {
505 if (cmd.Length < 5)
506 {
507 MainConsole.Instance.Output("Syntax: set region flags <region name> <flags>");
508 return;
509 }
510
511 List<RegionData> regions = m_Database.Get(cmd[3], UUID.Zero);
512 if (regions == null || regions.Count < 1)
513 {
514 MainConsole.Instance.Output("Region not found");
515 return;
516 }
517
518 foreach (RegionData r in regions)
519 {
520 int flags = Convert.ToInt32(r.Data["flags"]);
521 flags = ParseFlags(flags, cmd[4]);
522 r.Data["flags"] = flags.ToString();
523 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)flags;
524
525 MainConsole.Instance.Output(String.Format("Set region {0} to {1}", r.RegionName, f));
526 m_Database.Store(r);
527 }
528 }
246 } 529 }
247} 530}
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
new file mode 100644
index 0000000..af603b2
--- /dev/null
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -0,0 +1,641 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using System.Xml;
33
34using Nini.Config;
35using log4net;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Data;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
43using OpenMetaverse;
44
45namespace OpenSim.Services.GridService
46{
47 public class HypergridLinker
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType);
52
53 private static UUID m_HGMapImage = new UUID("00000000-0000-1111-9999-000000000013");
54
55 private static uint m_autoMappingX = 0;
56 private static uint m_autoMappingY = 0;
57 private static bool m_enableAutoMapping = false;
58
59 protected IRegionData m_Database;
60 protected GridService m_GridService;
61 protected IAssetService m_AssetService;
62 protected GatekeeperServiceConnector m_GatekeeperConnector;
63
64 protected UUID m_ScopeID = UUID.Zero;
65
66 // Hyperlink regions are hyperlinks on the map
67 public readonly Dictionary<UUID, GridRegion> m_HyperlinkRegions = new Dictionary<UUID, GridRegion>();
68 protected Dictionary<UUID, ulong> m_HyperlinkHandles = new Dictionary<UUID, ulong>();
69
70 protected GridRegion m_DefaultRegion;
71 protected GridRegion DefaultRegion
72 {
73 get
74 {
75 if (m_DefaultRegion == null)
76 {
77 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
78 if (defs != null && defs.Count > 0)
79 m_DefaultRegion = defs[0];
80 else
81 {
82 // Get any region
83 defs = m_GridService.GetRegionsByName(m_ScopeID, "", 1);
84 if (defs != null && defs.Count > 0)
85 m_DefaultRegion = defs[0];
86 else
87 {
88 // This shouldn't happen
89 m_DefaultRegion = new GridRegion(1000, 1000);
90 m_log.Error("[HYPERGRID LINKER]: Something is wrong with this grid. It has no regions?");
91 }
92 }
93 }
94 return m_DefaultRegion;
95 }
96 }
97
98 public HypergridLinker(IConfigSource config, GridService gridService, IRegionData db)
99 {
100 m_log.DebugFormat("[HYPERGRID LINKER]: Starting with db {0}", db.GetType());
101
102 m_Database = db;
103 m_GridService = gridService;
104
105 IConfig gridConfig = config.Configs["GridService"];
106 if (gridConfig != null)
107 {
108 string assetService = gridConfig.GetString("AssetService", string.Empty);
109
110 Object[] args = new Object[] { config };
111
112 if (assetService != string.Empty)
113 m_AssetService = ServerUtils.LoadPlugin<IAssetService>(assetService, args);
114
115 string scope = gridConfig.GetString("ScopeID", string.Empty);
116 if (scope != string.Empty)
117 UUID.TryParse(scope, out m_ScopeID);
118
119 m_GatekeeperConnector = new GatekeeperServiceConnector(m_AssetService);
120
121 m_log.DebugFormat("[HYPERGRID LINKER]: Loaded all services...");
122 }
123
124 if (MainConsole.Instance != null)
125 {
126 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region",
127 "link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>] <cr>",
128 "Link a hypergrid region", RunCommand);
129 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region",
130 "unlink-region <local name> or <HostName>:<HttpPort> <cr>",
131 "Unlink a hypergrid region", RunCommand);
132 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [<x> <y>] <cr>",
133 "Set local coordinate to map HG regions to", RunCommand);
134 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks <cr>",
135 "List the HG regions", HandleShow);
136 }
137 }
138
139
140 #region Link Region
141
142 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
143 {
144 string reason = string.Empty;
145 int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize;
146 return TryLinkRegionToCoords(scopeID, regionDescriptor, xloc, 0, out reason);
147 }
148
149 private static Random random = new Random();
150
151 // From the command line link-region
152 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason)
153 {
154 reason = string.Empty;
155 string host = "127.0.0.1";
156 string portstr;
157 string regionName = "";
158 uint port = 9000;
159 string[] parts = mapName.Split(new char[] { ':' });
160 if (parts.Length >= 1)
161 {
162 host = parts[0];
163 }
164 if (parts.Length >= 2)
165 {
166 portstr = parts[1];
167 //m_log.Debug("-- port = " + portstr);
168 if (!UInt32.TryParse(portstr, out port))
169 regionName = parts[1];
170 }
171 // always take the last one
172 if (parts.Length >= 3)
173 {
174 regionName = parts[2];
175 }
176
177 // Sanity check.
178 //IPAddress ipaddr = null;
179 try
180 {
181 //ipaddr = Util.GetHostFromDNS(host);
182 Util.GetHostFromDNS(host);
183 }
184 catch
185 {
186 reason = "Malformed hostname";
187 return null;
188 }
189
190 GridRegion regInfo;
191 bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, out regInfo, out reason);
192 if (success)
193 {
194 regInfo.RegionName = mapName;
195 return regInfo;
196 }
197
198 return null;
199 }
200
201
202 // From the command line and the 2 above
203 public bool TryCreateLink(UUID scopeID, int xloc, int yloc,
204 string externalRegionName, uint externalPort, string externalHostName, out GridRegion regInfo, out string reason)
205 {
206 m_log.DebugFormat("[HYPERGRID LINKER]: Link to {0}:{1}:{2}, in {3}-{4}", externalHostName, externalPort, externalRegionName, xloc, yloc);
207
208 reason = string.Empty;
209 regInfo = new GridRegion();
210 regInfo.RegionName = externalRegionName;
211 regInfo.HttpPort = externalPort;
212 regInfo.ExternalHostName = externalHostName;
213 regInfo.RegionLocX = xloc;
214 regInfo.RegionLocY = yloc;
215 regInfo.ScopeID = scopeID;
216
217 try
218 {
219 regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
220 }
221 catch (Exception e)
222 {
223 m_log.Warn("[HYPERGRID LINKER]: Wrong format for link-region: " + e.Message);
224 reason = "Internal error";
225 return false;
226 }
227
228 // Finally, link it
229 ulong handle = 0;
230 UUID regionID = UUID.Zero;
231 string externalName = string.Empty;
232 string imageURL = string.Empty;
233 if (!m_GatekeeperConnector.LinkRegion(regInfo, out regionID, out handle, out externalName, out imageURL, out reason))
234 return false;
235
236 if (regionID != UUID.Zero)
237 {
238 GridRegion r = m_GridService.GetRegionByUUID(scopeID, regionID);
239 if (r != null)
240 {
241 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}", r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize);
242 regInfo = r;
243 return true;
244 }
245
246 regInfo.RegionID = regionID;
247 Uri uri = null;
248 try
249 {
250 uri = new Uri(externalName);
251 regInfo.ExternalHostName = uri.Host;
252 regInfo.HttpPort = (uint)uri.Port;
253 }
254 catch
255 {
256 m_log.WarnFormat("[HYPERGRID LINKER]: Remote Gatekeeper at {0} provided malformed ExternalName {1}", regInfo.ExternalHostName, externalName);
257 }
258 regInfo.RegionName = regInfo.ExternalHostName + ":" + regInfo.HttpPort + ":" + regInfo.RegionName;
259 // Try get the map image
260 //regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL);
261 // I need a texture that works for this... the one I tried doesn't seem to be working
262 regInfo.TerrainImage = m_HGMapImage;
263
264 AddHyperlinkRegion(regInfo, handle);
265 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID);
266
267 }
268 else
269 {
270 m_log.Warn("[HYPERGRID LINKER]: Unable to link region");
271 reason = "Remote region could not be found";
272 return false;
273 }
274
275 uint x, y;
276 if (!Check4096(handle, out x, out y))
277 {
278 RemoveHyperlinkRegion(regInfo.RegionID);
279 reason = "Region is too far (" + x + ", " + y + ")";
280 m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
281 return false;
282 }
283
284 m_log.Debug("[HYPERGRID LINKER]: link region succeeded");
285 return true;
286 }
287
288 public bool TryUnlinkRegion(string mapName)
289 {
290 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName);
291 GridRegion regInfo = null;
292
293 List<RegionData> regions = m_Database.Get(mapName, m_ScopeID);
294 if (regions != null && regions.Count > 0)
295 {
296 OpenSim.Data.RegionFlags rflags = (OpenSim.Data.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]);
297 if ((rflags & OpenSim.Data.RegionFlags.Hyperlink) != 0)
298 {
299 regInfo = new GridRegion();
300 regInfo.RegionID = regions[0].RegionID;
301 regInfo.ScopeID = m_ScopeID;
302 }
303 }
304
305 //foreach (GridRegion r in m_HyperlinkRegions.Values)
306 //{
307 // m_log.DebugFormat("XXX Comparing {0}:{1} with {2}:{3}", host, port, r.ExternalHostName, r.HttpPort);
308 // if (host.Equals(r.ExternalHostName) && (port == r.HttpPort))
309 // regInfo = r;
310 //}
311
312 if (regInfo != null)
313 {
314 RemoveHyperlinkRegion(regInfo.RegionID);
315 return true;
316 }
317 else
318 {
319 m_log.InfoFormat("[HYPERGRID LINKER]: Region {0} not found", mapName);
320 return false;
321 }
322 }
323
324 /// <summary>
325 /// Cope with this viewer limitation.
326 /// </summary>
327 /// <param name="regInfo"></param>
328 /// <returns></returns>
329 public bool Check4096(ulong realHandle, out uint x, out uint y)
330 {
331 GridRegion defRegion = DefaultRegion;
332
333 uint ux = 0, uy = 0;
334 Utils.LongToUInts(realHandle, out ux, out uy);
335 x = ux / Constants.RegionSize;
336 y = uy / Constants.RegionSize;
337
338 if ((Math.Abs((int)defRegion.RegionLocX - ux) >= 4096 * Constants.RegionSize) ||
339 (Math.Abs((int)defRegion.RegionLocY - uy) >= 4096 * Constants.RegionSize))
340 {
341 return false;
342 }
343 return true;
344 }
345
346 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
347 {
348 //m_HyperlinkRegions[regionInfo.RegionID] = regionInfo;
349 //m_HyperlinkHandles[regionInfo.RegionID] = regionHandle;
350
351 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
352 int flags = (int)OpenSim.Data.RegionFlags.Hyperlink + (int)OpenSim.Data.RegionFlags.NoDirectLogin + (int)OpenSim.Data.RegionFlags.RegionOnline;
353 rdata.Data["flags"] = flags.ToString();
354
355 m_Database.Store(rdata);
356
357 }
358
359 private void RemoveHyperlinkRegion(UUID regionID)
360 {
361 //// Try the hyperlink collection
362 //if (m_HyperlinkRegions.ContainsKey(regionID))
363 //{
364 // m_HyperlinkRegions.Remove(regionID);
365 // m_HyperlinkHandles.Remove(regionID);
366 //}
367 m_Database.Delete(regionID);
368 }
369
370 #endregion
371
372
373 #region Console Commands
374
375 public void HandleShow(string module, string[] cmd)
376 {
377 MainConsole.Instance.Output("Not Implemented Yet");
378 //if (cmd.Length != 2)
379 //{
380 // MainConsole.Instance.Output("Syntax: show hyperlinks");
381 // return;
382 //}
383 //List<GridRegion> regions = new List<GridRegion>(m_HypergridService.m_HyperlinkRegions.Values);
384 //if (regions == null || regions.Count < 1)
385 //{
386 // MainConsole.Instance.Output("No hyperlinks");
387 // return;
388 //}
389
390 //MainConsole.Instance.Output("Region Name Region UUID");
391 //MainConsole.Instance.Output("Location URI");
392 //MainConsole.Instance.Output("Owner ID ");
393 //MainConsole.Instance.Output("-------------------------------------------------------------------------------");
394 //foreach (GridRegion r in regions)
395 //{
396 // MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} \n\n",
397 // r.RegionName, r.RegionID,
398 // String.Format("{0},{1}", r.RegionLocX, r.RegionLocY), "http://" + r.ExternalHostName + ":" + r.HttpPort.ToString(),
399 // r.EstateOwner.ToString()));
400 //}
401 //return;
402 }
403 public void RunCommand(string module, string[] cmdparams)
404 {
405 List<string> args = new List<string>(cmdparams);
406 if (args.Count < 1)
407 return;
408
409 string command = args[0];
410 args.RemoveAt(0);
411
412 cmdparams = args.ToArray();
413
414 RunHGCommand(command, cmdparams);
415
416 }
417
418 private void RunHGCommand(string command, string[] cmdparams)
419 {
420 if (command.Equals("link-mapping"))
421 {
422 if (cmdparams.Length == 2)
423 {
424 try
425 {
426 m_autoMappingX = Convert.ToUInt32(cmdparams[0]);
427 m_autoMappingY = Convert.ToUInt32(cmdparams[1]);
428 m_enableAutoMapping = true;
429 }
430 catch (Exception)
431 {
432 m_autoMappingX = 0;
433 m_autoMappingY = 0;
434 m_enableAutoMapping = false;
435 }
436 }
437 }
438 else if (command.Equals("link-region"))
439 {
440 if (cmdparams.Length < 3)
441 {
442 if ((cmdparams.Length == 1) || (cmdparams.Length == 2))
443 {
444 LoadXmlLinkFile(cmdparams);
445 }
446 else
447 {
448 LinkRegionCmdUsage();
449 }
450 return;
451 }
452
453 if (cmdparams[2].Contains(":"))
454 {
455 // New format
456 int xloc, yloc;
457 string mapName;
458 try
459 {
460 xloc = Convert.ToInt32(cmdparams[0]);
461 yloc = Convert.ToInt32(cmdparams[1]);
462 mapName = cmdparams[2];
463 if (cmdparams.Length > 3)
464 for (int i = 3; i < cmdparams.Length; i++)
465 mapName += " " + cmdparams[i];
466
467 //m_log.Info(">> MapName: " + mapName);
468 }
469 catch (Exception e)
470 {
471 MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
472 LinkRegionCmdUsage();
473 return;
474 }
475
476 // Convert cell coordinates given by the user to meters
477 xloc = xloc * (int)Constants.RegionSize;
478 yloc = yloc * (int)Constants.RegionSize;
479 string reason = string.Empty;
480 if (TryLinkRegionToCoords(UUID.Zero, mapName, xloc, yloc, out reason) == null)
481 MainConsole.Instance.Output("Failed to link region: " + reason);
482 else
483 MainConsole.Instance.Output("Hyperlink established");
484 }
485 else
486 {
487 // old format
488 GridRegion regInfo;
489 int xloc, yloc;
490 uint externalPort;
491 string externalHostName;
492 try
493 {
494 xloc = Convert.ToInt32(cmdparams[0]);
495 yloc = Convert.ToInt32(cmdparams[1]);
496 externalPort = Convert.ToUInt32(cmdparams[3]);
497 externalHostName = cmdparams[2];
498 //internalPort = Convert.ToUInt32(cmdparams[4]);
499 //remotingPort = Convert.ToUInt32(cmdparams[5]);
500 }
501 catch (Exception e)
502 {
503 MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message);
504 LinkRegionCmdUsage();
505 return;
506 }
507
508 // Convert cell coordinates given by the user to meters
509 xloc = xloc * (int)Constants.RegionSize;
510 yloc = yloc * (int)Constants.RegionSize;
511 string reason = string.Empty;
512 if (TryCreateLink(UUID.Zero, xloc, yloc, "", externalPort, externalHostName, out regInfo, out reason))
513 {
514 if (cmdparams.Length >= 5)
515 {
516 regInfo.RegionName = "";
517 for (int i = 4; i < cmdparams.Length; i++)
518 regInfo.RegionName += cmdparams[i] + " ";
519 }
520 }
521 }
522 return;
523 }
524 else if (command.Equals("unlink-region"))
525 {
526 if (cmdparams.Length < 1)
527 {
528 UnlinkRegionCmdUsage();
529 return;
530 }
531 if (TryUnlinkRegion(cmdparams[0]))
532 MainConsole.Instance.Output("Successfully unlinked " + cmdparams[0]);
533 else
534 MainConsole.Instance.Output("Unable to unlink " + cmdparams[0] + ", region not found.");
535 }
536 }
537
538 private void LoadXmlLinkFile(string[] cmdparams)
539 {
540 //use http://www.hgurl.com/hypergrid.xml for test
541 try
542 {
543 XmlReader r = XmlReader.Create(cmdparams[0]);
544 XmlConfigSource cs = new XmlConfigSource(r);
545 string[] excludeSections = null;
546
547 if (cmdparams.Length == 2)
548 {
549 if (cmdparams[1].ToLower().StartsWith("excludelist:"))
550 {
551 string excludeString = cmdparams[1].ToLower();
552 excludeString = excludeString.Remove(0, 12);
553 char[] splitter = { ';' };
554
555 excludeSections = excludeString.Split(splitter);
556 }
557 }
558
559 for (int i = 0; i < cs.Configs.Count; i++)
560 {
561 bool skip = false;
562 if ((excludeSections != null) && (excludeSections.Length > 0))
563 {
564 for (int n = 0; n < excludeSections.Length; n++)
565 {
566 if (excludeSections[n] == cs.Configs[i].Name.ToLower())
567 {
568 skip = true;
569 break;
570 }
571 }
572 }
573 if (!skip)
574 {
575 ReadLinkFromConfig(cs.Configs[i]);
576 }
577 }
578 }
579 catch (Exception e)
580 {
581 m_log.Error(e.ToString());
582 }
583 }
584
585
586 private void ReadLinkFromConfig(IConfig config)
587 {
588 GridRegion regInfo;
589 int xloc, yloc;
590 uint externalPort;
591 string externalHostName;
592 uint realXLoc, realYLoc;
593
594 xloc = Convert.ToInt32(config.GetString("xloc", "0"));
595 yloc = Convert.ToInt32(config.GetString("yloc", "0"));
596 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
597 externalHostName = config.GetString("externalHostName", "");
598 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
599 realYLoc = Convert.ToUInt32(config.GetString("real-yloc", "0"));
600
601 if (m_enableAutoMapping)
602 {
603 xloc = (int)((xloc % 100) + m_autoMappingX);
604 yloc = (int)((yloc % 100) + m_autoMappingY);
605 }
606
607 if (((realXLoc == 0) && (realYLoc == 0)) ||
608 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
609 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
610 {
611 xloc = xloc * (int)Constants.RegionSize;
612 yloc = yloc * (int)Constants.RegionSize;
613 string reason = string.Empty;
614 if (TryCreateLink(UUID.Zero, xloc, yloc, "", externalPort,
615 externalHostName, out regInfo, out reason))
616 {
617 regInfo.RegionName = config.GetString("localName", "");
618 }
619 else
620 MainConsole.Instance.Output("Unable to link " + externalHostName + ": " + reason);
621 }
622 }
623
624
625 private void LinkRegionCmdUsage()
626 {
627 MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <HostName>:<HttpPort>[:<RemoteRegionName>]");
628 MainConsole.Instance.Output("Usage: link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
629 MainConsole.Instance.Output("Usage: link-region <URI_of_xml> [<exclude>]");
630 }
631
632 private void UnlinkRegionCmdUsage()
633 {
634 MainConsole.Instance.Output("Usage: unlink-region <HostName>:<HttpPort>");
635 MainConsole.Instance.Output("Usage: unlink-region <LocalName>");
636 }
637
638 #endregion
639
640 }
641}
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
new file mode 100644
index 0000000..c5cfe75
--- /dev/null
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -0,0 +1,322 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Services.Interfaces;
35using GridRegion = OpenSim.Services.Interfaces.GridRegion;
36using OpenSim.Server.Base;
37using OpenSim.Services.Connectors.Hypergrid;
38
39using OpenMetaverse;
40
41using Nini.Config;
42using log4net;
43
44namespace OpenSim.Services.HypergridService
45{
46 public class GatekeeperService : IGatekeeperService
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(
50 MethodBase.GetCurrentMethod().DeclaringType);
51
52 IGridService m_GridService;
53 IPresenceService m_PresenceService;
54 IUserAccountService m_UserAccountService;
55 IUserAgentService m_UserAgentService;
56 ISimulationService m_SimulationService;
57
58 string m_AuthDll;
59
60 UUID m_ScopeID;
61 bool m_AllowTeleportsToAnyRegion;
62 string m_ExternalName;
63 GridRegion m_DefaultGatewayRegion;
64
65 public GatekeeperService(IConfigSource config, ISimulationService simService)
66 {
67 IConfig serverConfig = config.Configs["GatekeeperService"];
68 if (serverConfig == null)
69 throw new Exception(String.Format("No section GatekeeperService in config file"));
70
71 string accountService = serverConfig.GetString("UserAccountService", String.Empty);
72 string homeUsersService = serverConfig.GetString("HomeUsersSecurityService", string.Empty);
73 string gridService = serverConfig.GetString("GridService", String.Empty);
74 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
75 string simulationService = serverConfig.GetString("SimulationService", String.Empty);
76
77 //m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty);
78
79 // These 3 are mandatory, the others aren't
80 if (gridService == string.Empty || presenceService == string.Empty || m_AuthDll == string.Empty)
81 throw new Exception("Incomplete specifications, Gatekeeper Service cannot function.");
82
83 string scope = serverConfig.GetString("ScopeID", UUID.Zero.ToString());
84 UUID.TryParse(scope, out m_ScopeID);
85 //m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
86 m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true);
87 m_ExternalName = serverConfig.GetString("ExternalName", string.Empty);
88
89 Object[] args = new Object[] { config };
90 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
91 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
92
93 if (accountService != string.Empty)
94 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
95 if (homeUsersService != string.Empty)
96 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(homeUsersService, args);
97
98 if (simService != null)
99 m_SimulationService = simService;
100 else if (simulationService != string.Empty)
101 m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
102
103 if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
104 throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
105
106 m_log.Debug("[GATEKEEPER SERVICE]: Starting...");
107 }
108
109 public GatekeeperService(IConfigSource config)
110 : this(config, null)
111 {
112 }
113
114 public bool LinkRegion(string regionName, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason)
115 {
116 regionID = UUID.Zero;
117 regionHandle = 0;
118 externalName = m_ExternalName;
119 imageURL = string.Empty;
120 reason = string.Empty;
121
122
123 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName);
124 if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty)
125 {
126 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
127 if (defs != null && defs.Count > 0)
128 m_DefaultGatewayRegion = defs[0];
129
130 try
131 {
132 regionID = m_DefaultGatewayRegion.RegionID;
133 regionHandle = m_DefaultGatewayRegion.RegionHandle;
134 }
135 catch
136 {
137 reason = "Grid setup problem. Try specifying a particular region here.";
138 m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!");
139 return false;
140 }
141
142 return true;
143 }
144
145 GridRegion region = m_GridService.GetRegionByName(m_ScopeID, regionName);
146 if (region == null)
147 {
148 reason = "Region not found";
149 return false;
150 }
151
152 regionID = region.RegionID;
153 regionHandle = region.RegionHandle;
154 string regionimage = "regionImage" + region.RegionID.ToString();
155 regionimage = regionimage.Replace("-", "");
156
157 imageURL = "http://" + region.ExternalHostName + ":" + region.HttpPort + "/index.php?method=" + regionimage;
158
159 return true;
160 }
161
162 public GridRegion GetHyperlinkRegion(UUID regionID)
163 {
164 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to get hyperlink region {0}", regionID);
165
166 if (!m_AllowTeleportsToAnyRegion)
167 // Don't even check the given regionID
168 return m_DefaultGatewayRegion;
169
170 GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID);
171 return region;
172 }
173
174 #region Login Agent
175 public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason)
176 {
177 reason = string.Empty;
178
179 string authURL = string.Empty;
180 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
181 authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
182 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}",
183 aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName);
184
185 //
186 // Authenticate the user
187 //
188 if (!Authenticate(aCircuit))
189 {
190 reason = "Unable to verify identity";
191 m_log.InfoFormat("[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service.", aCircuit.firstname, aCircuit.lastname);
192 return false;
193 }
194 m_log.DebugFormat("[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL);
195
196 //
197 // Check for impersonations
198 //
199 UserAccount account = null;
200 if (m_UserAccountService != null)
201 {
202 // Check to see if we have a local user with that UUID
203 account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID);
204 if (account != null)
205 {
206 // Make sure this is the user coming home, and not a foreign user with same UUID as a local user
207 if (m_UserAgentService != null)
208 {
209 if (!m_UserAgentService.AgentIsComingHome(aCircuit.SessionID, m_ExternalName))
210 {
211 // Can't do, sorry
212 reason = "Unauthorized";
213 m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.",
214 aCircuit.firstname, aCircuit.lastname);
215 return false;
216
217 }
218 }
219 }
220 }
221 m_log.DebugFormat("[GATEKEEPER SERVICE]: User is ok");
222
223 // May want to authorize
224
225 //
226 // Login the presence
227 //
228 if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID))
229 {
230 reason = "Unable to login presence";
231 m_log.InfoFormat("[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service.",
232 aCircuit.firstname, aCircuit.lastname);
233 return false;
234 }
235 m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok");
236
237 //
238 // Get the region
239 //
240 destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID);
241 if (destination == null)
242 {
243 reason = "Destination region not found";
244 return false;
245 }
246 m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok: {0}", destination.RegionName);
247
248 //
249 // Adjust the visible name
250 //
251 if (account != null)
252 {
253 aCircuit.firstname = account.FirstName;
254 aCircuit.lastname = account.LastName;
255 }
256 if (account == null && !aCircuit.lastname.StartsWith("@"))
257 {
258 aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname;
259 aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString();
260 }
261
262 //
263 // Finally launch the agent at the destination
264 //
265 return m_SimulationService.CreateAgent(destination, aCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
266 }
267
268 protected bool Authenticate(AgentCircuitData aCircuit)
269 {
270 if (!CheckAddress(aCircuit.ServiceSessionID))
271 return false;
272
273 string userURL = string.Empty;
274 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
275 userURL = aCircuit.ServiceURLs["HomeURI"].ToString();
276
277 if (userURL == string.Empty)
278 {
279 m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL");
280 return false;
281 }
282
283 Object[] args = new Object[] { userURL };
284 IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); //ServerUtils.LoadPlugin<IUserAgentService>(m_AuthDll, args);
285 if (userAgentService != null)
286 {
287 try
288 {
289 return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
290 }
291 catch
292 {
293 m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL);
294 return false;
295 }
296 }
297
298 return false;
299 }
300
301 // Check that the service token was generated for *this* grid.
302 // If it wasn't then that's a fake agent.
303 protected bool CheckAddress(string serviceToken)
304 {
305 string[] parts = serviceToken.Split(new char[] { ';' });
306 if (parts.Length < 2)
307 return false;
308
309 string addressee = parts[0];
310 m_log.DebugFormat("[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, m_ExternalName);
311 return (addressee == m_ExternalName);
312 }
313
314 #endregion
315
316
317 #region Misc
318
319
320 #endregion
321 }
322}
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
new file mode 100644
index 0000000..2f1fed4
--- /dev/null
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Services.Connectors.Hypergrid;
35using OpenSim.Services.Interfaces;
36using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37using OpenSim.Server.Base;
38
39using OpenMetaverse;
40using log4net;
41using Nini.Config;
42
43namespace OpenSim.Services.HypergridService
44{
45 /// <summary>
46 /// This service is for HG1.5 only, to make up for the fact that clients don't
47 /// keep any private information in themselves, and that their 'home service'
48 /// needs to do it for them.
49 /// Once we have better clients, this shouldn't be needed.
50 /// </summary>
51 public class UserAgentService : IUserAgentService
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56
57 // This will need to go into a DB table
58 static Dictionary<UUID, TravelingAgentInfo> m_TravelingAgents = new Dictionary<UUID, TravelingAgentInfo>();
59
60 static bool m_Initialized = false;
61
62 protected static IGridUserService m_GridUserService;
63 protected static IGridService m_GridService;
64 protected static GatekeeperServiceConnector m_GatekeeperConnector;
65
66 public UserAgentService(IConfigSource config)
67 {
68 if (!m_Initialized)
69 {
70 m_log.DebugFormat("[HOME USERS SECURITY]: Starting...");
71
72 IConfig serverConfig = config.Configs["UserAgentService"];
73 if (serverConfig == null)
74 throw new Exception(String.Format("No section UserAgentService in config file"));
75
76 string gridService = serverConfig.GetString("GridService", String.Empty);
77 string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
78
79 if (gridService == string.Empty || gridUserService == string.Empty)
80 throw new Exception(String.Format("Incomplete specifications, UserAgent Service cannot function."));
81
82 Object[] args = new Object[] { config };
83 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
84 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
85 m_GatekeeperConnector = new GatekeeperServiceConnector();
86
87 m_Initialized = true;
88 }
89 }
90
91 public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
92 {
93 position = new Vector3(128, 128, 0); lookAt = Vector3.UnitY;
94
95 m_log.DebugFormat("[USER AGENT SERVICE]: Request to get home region of user {0}", userID);
96
97 GridRegion home = null;
98 GridUserInfo uinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
99 if (uinfo != null)
100 {
101 if (uinfo.HomeRegionID != UUID.Zero)
102 {
103 home = m_GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
104 position = uinfo.HomePosition;
105 lookAt = uinfo.HomeLookAt;
106 }
107 if (home == null)
108 {
109 List<GridRegion> defs = m_GridService.GetDefaultRegions(UUID.Zero);
110 if (defs != null && defs.Count > 0)
111 home = defs[0];
112 }
113 }
114
115 return home;
116 }
117
118 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
119 {
120 m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} to grid {2}",
121 agentCircuit.firstname, agentCircuit.lastname, gatekeeper.ExternalHostName +":"+ gatekeeper.HttpPort);
122
123 // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination
124 GridRegion region = new GridRegion(gatekeeper);
125 region.RegionName = finalDestination.RegionName;
126 region.RegionID = finalDestination.RegionID;
127 region.RegionLocX = finalDestination.RegionLocX;
128 region.RegionLocY = finalDestination.RegionLocY;
129
130 // Generate a new service session
131 agentCircuit.ServiceSessionID = "http://" + region.ExternalHostName + ":" + region.HttpPort + ";" + UUID.Random();
132 TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region);
133
134 bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
135
136 if (!success)
137 {
138 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}",
139 agentCircuit.firstname, agentCircuit.lastname, region.ExternalHostName + ":" + region.HttpPort, reason);
140
141 // restore the old travel info
142 lock (m_TravelingAgents)
143 m_TravelingAgents[agentCircuit.SessionID] = old;
144
145 return false;
146 }
147
148 return true;
149 }
150
151 public void SetClientToken(UUID sessionID, string token)
152 {
153 if (m_TravelingAgents.ContainsKey(sessionID))
154 {
155 m_log.DebugFormat("[USER AGENT SERVICE]: Setting token {0} for session {1}", token, sessionID);
156 m_TravelingAgents[sessionID].ClientToken = token;
157 }
158 }
159
160 TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region)
161 {
162 TravelingAgentInfo travel = new TravelingAgentInfo();
163 TravelingAgentInfo old = null;
164 lock (m_TravelingAgents)
165 {
166 if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID))
167 {
168 old = m_TravelingAgents[agentCircuit.SessionID];
169 }
170
171 m_TravelingAgents[agentCircuit.SessionID] = travel;
172 }
173 travel.UserID = agentCircuit.AgentID;
174 travel.GridExternalName = region.ExternalHostName + ":" + region.HttpPort;
175 travel.ServiceToken = agentCircuit.ServiceSessionID;
176 if (old != null)
177 travel.ClientToken = old.ClientToken;
178
179 return old;
180 }
181
182 public void LogoutAgent(UUID userID, UUID sessionID)
183 {
184 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
185
186 lock (m_TravelingAgents)
187 {
188 List<UUID> travels = new List<UUID>();
189 foreach (KeyValuePair<UUID, TravelingAgentInfo> kvp in m_TravelingAgents)
190 if (kvp.Value == null) // do some clean up
191 travels.Add(kvp.Key);
192 else if (kvp.Value.UserID == userID)
193 travels.Add(kvp.Key);
194 foreach (UUID session in travels)
195 m_TravelingAgents.Remove(session);
196 }
197
198 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
199 if (guinfo != null)
200 m_GridUserService.LoggedOut(userID.ToString(), guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt);
201 }
202
203 // We need to prevent foreign users with the same UUID as a local user
204 public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName)
205 {
206 if (!m_TravelingAgents.ContainsKey(sessionID))
207 return false;
208
209 TravelingAgentInfo travel = m_TravelingAgents[sessionID];
210 return travel.GridExternalName == thisGridExternalName;
211 }
212
213 public bool VerifyClient(UUID sessionID, string token)
214 {
215 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token);
216 //return true;
217
218 // Commenting this for now until I understand better what part of a sender's
219 // info stays unchanged throughout a session
220
221 if (m_TravelingAgents.ContainsKey(sessionID))
222 return m_TravelingAgents[sessionID].ClientToken == token;
223
224 return false;
225 }
226
227 public bool VerifyAgent(UUID sessionID, string token)
228 {
229 if (m_TravelingAgents.ContainsKey(sessionID))
230 {
231 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken);
232 return m_TravelingAgents[sessionID].ServiceToken == token;
233 }
234
235 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
236
237 return false;
238 }
239
240 }
241
242 class TravelingAgentInfo
243 {
244 public UUID UserID;
245 public string GridExternalName = string.Empty;
246 public string ServiceToken = string.Empty;
247 public string ClientToken = string.Empty;
248 }
249
250}
diff --git a/OpenSim/Services/Interfaces/IAttachmentsService.cs b/OpenSim/Services/Interfaces/IAttachmentsService.cs
new file mode 100644
index 0000000..bdde369
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IAttachmentsService.cs
@@ -0,0 +1,17 @@
1////////////////////////////////////////////////////////////////
2//
3// (c) 2009, 2010 Careminster Limited and Melanie Thielker
4//
5// All rights reserved
6//
7using System;
8using Nini.Config;
9
10namespace OpenSim.Services.Interfaces
11{
12 public interface IAttachmentsService
13 {
14 string Get(string id);
15 void Store(string id, string data);
16 }
17}
diff --git a/OpenSim/Services/Interfaces/IAuthenticationService.cs b/OpenSim/Services/Interfaces/IAuthenticationService.cs
index 9225773..9de261b 100644
--- a/OpenSim/Services/Interfaces/IAuthenticationService.cs
+++ b/OpenSim/Services/Interfaces/IAuthenticationService.cs
@@ -66,6 +66,17 @@ namespace OpenSim.Services.Interfaces
66 bool Release(UUID principalID, string token); 66 bool Release(UUID principalID, string token);
67 67
68 ////////////////////////////////////////////////////// 68 //////////////////////////////////////////////////////
69 // SetPassword for a principal
70 //
71 // This method exists for the service, but may or may not
72 // be served remotely. That is, the authentication
73 // handlers may not include one handler for this,
74 // because it's a bit risky. Such handlers require
75 // authentication/authorization.
76 //
77 bool SetPassword(UUID principalID, string passwd);
78
79 //////////////////////////////////////////////////////
69 // Grid 80 // Grid
70 // 81 //
71 // We no longer need a shared secret between grid 82 // We no longer need a shared secret between grid
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
new file mode 100644
index 0000000..de3bcf9
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -0,0 +1,241 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31
32using OpenSim.Framework;
33
34using OpenMetaverse;
35
36namespace OpenSim.Services.Interfaces
37{
38 public interface IAvatarService
39 {
40 /// <summary>
41 /// Called by the login service
42 /// </summary>
43 /// <param name="userID"></param>
44 /// <returns></returns>
45 AvatarData GetAvatar(UUID userID);
46
47 /// <summary>
48 /// Called by everyone who can change the avatar data (so, regions)
49 /// </summary>
50 /// <param name="userID"></param>
51 /// <param name="avatar"></param>
52 /// <returns></returns>
53 bool SetAvatar(UUID userID, AvatarData avatar);
54
55 /// <summary>
56 /// Not sure if it's needed
57 /// </summary>
58 /// <param name="userID"></param>
59 /// <returns></returns>
60 bool ResetAvatar(UUID userID);
61
62 /// <summary>
63 /// These methods raison d'etre:
64 /// No need to send the entire avatar data (SetAvatar) for changing attachments
65 /// </summary>
66 /// <param name="userID"></param>
67 /// <param name="attach"></param>
68 /// <returns></returns>
69 bool SetItems(UUID userID, string[] names, string[] values);
70 bool RemoveItems(UUID userID, string[] names);
71 }
72
73 /// <summary>
74 /// Each region/client that uses avatars will have a data structure
75 /// of this type representing the avatars.
76 /// </summary>
77 public class AvatarData
78 {
79 // This pretty much determines which name/value pairs will be
80 // present below. The name/value pair describe a part of
81 // the avatar. For SL avatars, these would be "shape", "texture1",
82 // etc. For other avatars, they might be "mesh", "skin", etc.
83 // The value portion is a URL that is expected to resolve to an
84 // asset of the type required by the handler for that field.
85 // It is required that regions can access these URLs. Allowing
86 // direct access by a viewer is not required, and, if provided,
87 // may be read-only. A "naked" UUID can be used to refer to an
88 // asset int he current region's asset service, which is not
89 // portable, but allows legacy appearance to continue to
90 // function. Closed, LL-based grids will never need URLs here.
91
92 public int AvatarType;
93 public Dictionary<string,string> Data;
94
95 public AvatarData()
96 {
97 }
98
99 public AvatarData(Dictionary<string, object> kvp)
100 {
101 Data = new Dictionary<string, string>();
102
103 if (kvp.ContainsKey("AvatarType"))
104 Int32.TryParse(kvp["AvatarType"].ToString(), out AvatarType);
105
106 foreach (KeyValuePair<string, object> _kvp in kvp)
107 {
108 if (_kvp.Value != null)
109 Data[_kvp.Key] = _kvp.Value.ToString();
110 }
111 }
112
113 /// <summary>
114 /// </summary>
115 /// <returns></returns>
116 public Dictionary<string, object> ToKeyValuePairs()
117 {
118 Dictionary<string, object> result = new Dictionary<string, object>();
119
120 result["AvatarType"] = AvatarType.ToString();
121 foreach (KeyValuePair<string, string> _kvp in Data)
122 {
123 if (_kvp.Value != null)
124 result[_kvp.Key] = _kvp.Value;
125 }
126 return result;
127 }
128
129 public AvatarData(AvatarAppearance appearance)
130 {
131 AvatarType = 1; // SL avatars
132 Data = new Dictionary<string, string>();
133
134 Data["Serial"] = appearance.Serial.ToString();
135 // Wearables
136 Data["AvatarHeight"] = appearance.AvatarHeight.ToString();
137 Data["BodyItem"] = appearance.BodyItem.ToString();
138 Data["EyesItem"] = appearance.EyesItem.ToString();
139 Data["GlovesItem"] = appearance.GlovesItem.ToString();
140 Data["HairItem"] = appearance.HairItem.ToString();
141 Data["JacketItem"] = appearance.JacketItem.ToString();
142 Data["PantsItem"] = appearance.PantsItem.ToString();
143 Data["ShirtItem"] = appearance.ShirtItem.ToString();
144 Data["ShoesItem"] = appearance.ShoesItem.ToString();
145 Data["SkinItem"] = appearance.SkinItem.ToString();
146 Data["SkirtItem"] = appearance.SkirtItem.ToString();
147 Data["SocksItem"] = appearance.SocksItem.ToString();
148 Data["UnderPantsItem"] = appearance.UnderPantsItem.ToString();
149 Data["UnderShirtItem"] = appearance.UnderShirtItem.ToString();
150
151 Data["BodyAsset"] = appearance.BodyAsset.ToString();
152 Data["EyesAsset"] = appearance.EyesAsset.ToString();
153 Data["GlovesAsset"] = appearance.GlovesAsset.ToString();
154 Data["HairAsset"] = appearance.HairAsset.ToString();
155 Data["JacketAsset"] = appearance.JacketAsset.ToString();
156 Data["PantsAsset"] = appearance.PantsAsset.ToString();
157 Data["ShirtAsset"] = appearance.ShirtAsset.ToString();
158 Data["ShoesAsset"] = appearance.ShoesAsset.ToString();
159 Data["SkinAsset"] = appearance.SkinAsset.ToString();
160 Data["SkirtAsset"] = appearance.SkirtAsset.ToString();
161 Data["SocksAsset"] = appearance.SocksAsset.ToString();
162 Data["UnderPantsAsset"] = appearance.UnderPantsAsset.ToString();
163 Data["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString();
164
165 // Attachments
166 Hashtable attachs = appearance.GetAttachments();
167 if (attachs != null)
168 foreach (DictionaryEntry dentry in attachs)
169 {
170 if (dentry.Value != null)
171 {
172 Hashtable tab = (Hashtable)dentry.Value;
173 if (tab.ContainsKey("item") && tab["item"] != null)
174 Data["_ap_" + dentry.Key] = tab["item"].ToString();
175 }
176 }
177 }
178
179 public AvatarAppearance ToAvatarAppearance(UUID owner)
180 {
181 AvatarAppearance appearance = new AvatarAppearance(owner);
182 try
183 {
184 appearance.Serial = Int32.Parse(Data["Serial"]);
185
186 // Wearables
187 appearance.BodyItem = UUID.Parse(Data["BodyItem"]);
188 appearance.EyesItem = UUID.Parse(Data["EyesItem"]);
189 appearance.GlovesItem = UUID.Parse(Data["GlovesItem"]);
190 appearance.HairItem = UUID.Parse(Data["HairItem"]);
191 appearance.JacketItem = UUID.Parse(Data["JacketItem"]);
192 appearance.PantsItem = UUID.Parse(Data["PantsItem"]);
193 appearance.ShirtItem = UUID.Parse(Data["ShirtItem"]);
194 appearance.ShoesItem = UUID.Parse(Data["ShoesItem"]);
195 appearance.SkinItem = UUID.Parse(Data["SkinItem"]);
196 appearance.SkirtItem = UUID.Parse(Data["SkirtItem"]);
197 appearance.SocksItem = UUID.Parse(Data["SocksItem"]);
198 appearance.UnderPantsItem = UUID.Parse(Data["UnderPantsItem"]);
199 appearance.UnderShirtItem = UUID.Parse(Data["UnderShirtItem"]);
200
201 appearance.BodyAsset = UUID.Parse(Data["BodyAsset"]);
202 appearance.EyesAsset = UUID.Parse(Data["EyesAsset"]);
203 appearance.GlovesAsset = UUID.Parse(Data["GlovesAsset"]);
204 appearance.HairAsset = UUID.Parse(Data["HairAsset"]);
205 appearance.JacketAsset = UUID.Parse(Data["JacketAsset"]);
206 appearance.PantsAsset = UUID.Parse(Data["PantsAsset"]);
207 appearance.ShirtAsset = UUID.Parse(Data["ShirtAsset"]);
208 appearance.ShoesAsset = UUID.Parse(Data["ShoesAsset"]);
209 appearance.SkinAsset = UUID.Parse(Data["SkinAsset"]);
210 appearance.SkirtAsset = UUID.Parse(Data["SkirtAsset"]);
211 appearance.SocksAsset = UUID.Parse(Data["SocksAsset"]);
212 appearance.UnderPantsAsset = UUID.Parse(Data["UnderPantsAsset"]);
213 appearance.UnderShirtAsset = UUID.Parse(Data["UnderShirtAsset"]);
214
215 // Attachments
216 Dictionary<string, string> attchs = new Dictionary<string, string>();
217 foreach (KeyValuePair<string, string> _kvp in Data)
218 if (_kvp.Key.StartsWith("_ap_"))
219 attchs[_kvp.Key] = _kvp.Value;
220 Hashtable aaAttachs = new Hashtable();
221 foreach (KeyValuePair<string, string> _kvp in attchs)
222 {
223 string pointStr = _kvp.Key.Substring(4);
224 int point = 0;
225 if (!Int32.TryParse(pointStr, out point))
226 continue;
227 Hashtable tmp = new Hashtable();
228 UUID uuid = UUID.Zero;
229 UUID.TryParse(_kvp.Value, out uuid);
230 tmp["item"] = uuid;
231 tmp["asset"] = UUID.Zero.ToString();
232 aaAttachs[point] = tmp;
233 }
234 appearance.SetAttachments(aaAttachs);
235 }
236 catch { }
237
238 return appearance;
239 }
240 }
241}
diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs
new file mode 100644
index 0000000..0ddd5e5
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IFriendsService.cs
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30using OpenSim.Framework;
31using System.Collections.Generic;
32
33namespace OpenSim.Services.Interfaces
34{
35 public class FriendInfo
36 {
37 public UUID PrincipalID;
38 public string Friend;
39 public int MyFlags;
40 public int TheirFlags;
41
42 public FriendInfo()
43 {
44 }
45
46 public FriendInfo(Dictionary<string, object> kvp)
47 {
48 PrincipalID = UUID.Zero;
49 if (kvp.ContainsKey("PrincipalID") && kvp["PrincipalID"] != null)
50 UUID.TryParse(kvp["PrincipalID"].ToString(), out PrincipalID);
51 Friend = string.Empty;
52 if (kvp.ContainsKey("Friend") && kvp["Friend"] != null)
53 Friend = kvp["Friend"].ToString();
54 MyFlags = 0;
55 if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null)
56 Int32.TryParse(kvp["MyFlags"].ToString(), out MyFlags);
57 TheirFlags = 0;
58 if (kvp.ContainsKey("TheirFlags") && kvp["TheirFlags"] != null)
59 Int32.TryParse(kvp["TheirFlags"].ToString(), out TheirFlags);
60 }
61
62 public Dictionary<string, object> ToKeyValuePairs()
63 {
64 Dictionary<string, object> result = new Dictionary<string, object>();
65 result["PrincipalID"] = PrincipalID.ToString();
66 result["Friend"] = Friend;
67 result["MyFlags"] = MyFlags.ToString();
68 result["TheirFlags"] = TheirFlags.ToString();
69
70 return result;
71 }
72 }
73
74 public interface IFriendsService
75 {
76 FriendInfo[] GetFriends(UUID PrincipalID);
77 bool StoreFriend(UUID PrincipalID, string Friend, int flags);
78 bool Delete(UUID PrincipalID, string Friend);
79 }
80}
diff --git a/OpenSim/Services/UserService/UserService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs
index e8b9fc3..2d397bc 100644
--- a/OpenSim/Services/UserService/UserService.cs
+++ b/OpenSim/Services/Interfaces/IGatekeeperService.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -26,51 +26,35 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Net;
30using Nini.Config;
31using OpenSim.Data;
32using OpenSim.Services.Interfaces;
33using System.Collections.Generic; 30using System.Collections.Generic;
31
32using OpenSim.Framework;
34using OpenMetaverse; 33using OpenMetaverse;
35 34
36namespace OpenSim.Services.UserAccountService 35namespace OpenSim.Services.Interfaces
37{ 36{
38 public class UserAccountService : UserAccountServiceBase, IUserAccountService 37 public interface IGatekeeperService
39 { 38 {
40 public UserAccountService(IConfigSource config) : base(config) 39 bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason);
41 { 40 GridRegion GetHyperlinkRegion(UUID regionID);
42 }
43
44 public UserAccount GetUserAccount(UUID scopeID, string firstName,
45 string lastName)
46 {
47 return null;
48 }
49
50 public UserAccount GetUserAccount(UUID scopeID, UUID userID)
51 {
52 return null;
53 }
54 41
55 public bool SetHomePosition(UserAccount data, UUID regionID, UUID regionSecret) 42 bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason);
56 {
57 return false;
58 }
59 43
60 public bool SetUserAccount(UserAccount data, UUID principalID, string token) 44 }
61 {
62 return false;
63 }
64
65 public bool CreateUserAccount(UserAccount data, UUID principalID, string token)
66 {
67 return false;
68 }
69 45
70 public List<UserAccount> GetUserAccount(UUID scopeID, 46 /// <summary>
71 string query) 47 /// HG1.5 only
72 { 48 /// </summary>
73 return null; 49 public interface IUserAgentService
74 } 50 {
51 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
52 void SetClientToken(UUID sessionID, string token);
53 void LogoutAgent(UUID userID, UUID sessionID);
54 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
55
56 bool AgentIsComingHome(UUID sessionID, string thisGridExternalName);
57 bool VerifyAgent(UUID sessionID, string token);
58 bool VerifyClient(UUID sessionID, string token);
75 } 59 }
76} 60}
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs
index 5135f6d..e55b633 100644
--- a/OpenSim/Services/Interfaces/IGridService.cs
+++ b/OpenSim/Services/Interfaces/IGridService.cs
@@ -90,6 +90,10 @@ namespace OpenSim.Services.Interfaces
90 90
91 List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax); 91 List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax);
92 92
93 List<GridRegion> GetDefaultRegions(UUID scopeID);
94 List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y);
95
96 int GetRegionFlags(UUID scopeID, UUID regionID);
93 } 97 }
94 98
95 public class GridRegion 99 public class GridRegion
@@ -154,7 +158,8 @@ namespace OpenSim.Services.Interfaces
154 public UUID TerrainImage = UUID.Zero; 158 public UUID TerrainImage = UUID.Zero;
155 public byte Access; 159 public byte Access;
156 public int Maturity; 160 public int Maturity;
157 public string RegionSecret; 161 public string RegionSecret = string.Empty;
162 public string Token = string.Empty;
158 163
159 public GridRegion() 164 public GridRegion()
160 { 165 {
@@ -200,12 +205,6 @@ namespace OpenSim.Services.Interfaces
200 Maturity = ConvertFrom.RegionSettings.Maturity; 205 Maturity = ConvertFrom.RegionSettings.Maturity;
201 RegionSecret = ConvertFrom.regionSecret; 206 RegionSecret = ConvertFrom.regionSecret;
202 EstateOwner = ConvertFrom.EstateSettings.EstateOwner; 207 EstateOwner = ConvertFrom.EstateSettings.EstateOwner;
203 if (EstateOwner == UUID.Zero)
204 {
205 EstateOwner = ConvertFrom.MasterAvatarAssignedUUID;
206 ConvertFrom.EstateSettings.EstateOwner = EstateOwner;
207 ConvertFrom.EstateSettings.Save();
208 }
209 } 208 }
210 209
211 public GridRegion(GridRegion ConvertFrom) 210 public GridRegion(GridRegion ConvertFrom)
@@ -267,8 +266,6 @@ namespace OpenSim.Services.Interfaces
267 266
268 return new IPEndPoint(ia, m_internalEndPoint.Port); 267 return new IPEndPoint(ia, m_internalEndPoint.Port);
269 } 268 }
270
271 set { m_externalHostName = value.ToString(); }
272 } 269 }
273 270
274 public string ExternalHostName 271 public string ExternalHostName
@@ -288,11 +285,6 @@ namespace OpenSim.Services.Interfaces
288 get { return Util.UIntsToLong((uint)RegionLocX, (uint)RegionLocY); } 285 get { return Util.UIntsToLong((uint)RegionLocX, (uint)RegionLocY); }
289 } 286 }
290 287
291 public int getInternalEndPointPort()
292 {
293 return m_internalEndPoint.Port;
294 }
295
296 public Dictionary<string, object> ToKeyValuePairs() 288 public Dictionary<string, object> ToKeyValuePairs()
297 { 289 {
298 Dictionary<string, object> kvp = new Dictionary<string, object>(); 290 Dictionary<string, object> kvp = new Dictionary<string, object>();
@@ -308,6 +300,7 @@ namespace OpenSim.Services.Interfaces
308 kvp["access"] = Access.ToString(); 300 kvp["access"] = Access.ToString();
309 kvp["regionSecret"] = RegionSecret; 301 kvp["regionSecret"] = RegionSecret;
310 kvp["owner_uuid"] = EstateOwner.ToString(); 302 kvp["owner_uuid"] = EstateOwner.ToString();
303 kvp["Token"] = Token.ToString();
311 // Maturity doesn't seem to exist in the DB 304 // Maturity doesn't seem to exist in the DB
312 return kvp; 305 return kvp;
313 } 306 }
@@ -365,6 +358,9 @@ namespace OpenSim.Services.Interfaces
365 if (kvp.ContainsKey("owner_uuid")) 358 if (kvp.ContainsKey("owner_uuid"))
366 EstateOwner = new UUID(kvp["owner_uuid"].ToString()); 359 EstateOwner = new UUID(kvp["owner_uuid"].ToString());
367 360
361 if (kvp.ContainsKey("Token"))
362 Token = kvp["Token"].ToString();
363
368 } 364 }
369 } 365 }
370 366
diff --git a/OpenSim/Services/Interfaces/IGridUserService.cs b/OpenSim/Services/Interfaces/IGridUserService.cs
new file mode 100644
index 0000000..e629dff
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IGridUserService.cs
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31
32namespace OpenSim.Services.Interfaces
33{
34 /// <summary>
35 /// Records user information specific to a grid but which is not part of a user's account.
36 /// </summary>
37 public class GridUserInfo
38 {
39 public string UserID;
40
41 public UUID HomeRegionID;
42 public Vector3 HomePosition;
43 public Vector3 HomeLookAt;
44
45 public UUID LastRegionID;
46 public Vector3 LastPosition;
47 public Vector3 LastLookAt;
48
49 public bool Online;
50 public DateTime Login;
51 public DateTime Logout;
52
53 public GridUserInfo() {}
54
55 public GridUserInfo(Dictionary<string, object> kvp)
56 {
57 if (kvp.ContainsKey("UserID"))
58 UserID = kvp["UserID"].ToString();
59
60 if (kvp.ContainsKey("HomeRegionID"))
61 UUID.TryParse(kvp["HomeRegionID"].ToString(), out HomeRegionID);
62 if (kvp.ContainsKey("HomePosition"))
63 Vector3.TryParse(kvp["HomePosition"].ToString(), out HomePosition);
64 if (kvp.ContainsKey("HomeLookAt"))
65 Vector3.TryParse(kvp["HomeLookAt"].ToString(), out HomeLookAt);
66
67 if (kvp.ContainsKey("LastRegionID"))
68 UUID.TryParse(kvp["LastRegionID"].ToString(), out HomeRegionID);
69 if (kvp.ContainsKey("LastPosition"))
70 Vector3.TryParse(kvp["LastPosition"].ToString(), out LastPosition);
71 if (kvp.ContainsKey("LastLookAt"))
72 Vector3.TryParse(kvp["LastLookAt"].ToString(), out LastLookAt);
73
74 if (kvp.ContainsKey("Login"))
75 DateTime.TryParse(kvp["Login"].ToString(), out Login);
76 if (kvp.ContainsKey("Logout"))
77 DateTime.TryParse(kvp["Logout"].ToString(), out Logout);
78 if (kvp.ContainsKey("Online"))
79 Boolean.TryParse(kvp["Online"].ToString(), out Online);
80
81 }
82
83 public Dictionary<string, object> ToKeyValuePairs()
84 {
85 Dictionary<string, object> result = new Dictionary<string, object>();
86 result["UserID"] = UserID;
87
88 result["HomeRegionID"] = HomeRegionID.ToString();
89 result["HomePosition"] = HomePosition.ToString();
90 result["HomeLookAt"] = HomeLookAt.ToString();
91
92 result["LastRegionID"] = LastRegionID.ToString();
93 result["LastPosition"] = LastPosition.ToString();
94 result["LastLookAt"] = LastLookAt.ToString();
95
96 result["Online"] = Online.ToString();
97 result["Login"] = Login.ToString();
98 result["Logout"] = Logout.ToString();
99
100
101 return result;
102 }
103 }
104
105 public interface IGridUserService
106 {
107 GridUserInfo LoggedIn(string userID);
108 bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
109
110 bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt);
111 bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
112
113 GridUserInfo GetGridUserInfo(string userID);
114 }
115} \ No newline at end of file
diff --git a/OpenSim/Services/Interfaces/IHyperlink.cs b/OpenSim/Services/Interfaces/ILibraryService.cs
index ed3ff23..861cf0e 100644
--- a/OpenSim/Services/Interfaces/IHyperlink.cs
+++ b/OpenSim/Services/Interfaces/ILibraryService.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -25,25 +25,19 @@
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
28using OpenSim.Framework; 28using System;
29using GridRegion = OpenSim.Services.Interfaces.GridRegion; 29using System.Collections.Generic;
30 30
31using OpenSim.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
32 33
33namespace OpenSim.Services.Interfaces 34namespace OpenSim.Services.Interfaces
34{ 35{
35 public interface IHyperlinkService 36 public interface ILibraryService
36 { 37 {
37 GridRegion TryLinkRegion(IClientAPI client, string regionDescriptor); 38 InventoryFolderImpl LibraryRootFolder { get; }
38 GridRegion GetHyperlinkRegion(ulong handle);
39 ulong FindRegionHandle(ulong handle);
40
41 bool SendUserInformation(GridRegion region, AgentCircuitData aCircuit);
42 void AdjustUserInformation(AgentCircuitData aCircuit);
43 39
44 bool CheckUserAtEntry(UUID userID, UUID sessionID, out bool comingHome); 40 Dictionary<UUID, InventoryFolderImpl> GetAllFolders();
45 void AcceptUser(ForeignUserProfileData user, GridRegion home);
46
47 bool IsLocalUser(UUID userID);
48 } 41 }
42
49} 43}
diff --git a/OpenSim/Services/Interfaces/ILoginService.cs b/OpenSim/Services/Interfaces/ILoginService.cs
new file mode 100644
index 0000000..9e57339
--- /dev/null
+++ b/OpenSim/Services/Interfaces/ILoginService.cs
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32
33using OpenMetaverse.StructuredData;
34using OpenMetaverse;
35
36namespace OpenSim.Services.Interfaces
37{
38 public abstract class LoginResponse
39 {
40 public abstract Hashtable ToHashtable();
41 public abstract OSD ToOSDMap();
42 }
43
44 public abstract class FailedLoginResponse : LoginResponse
45 {
46 }
47
48 public interface ILoginService
49 {
50 LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, string clientVersion, IPEndPoint clientIP);
51 Hashtable SetLevel(string firstName, string lastName, string passwd, int level, IPEndPoint clientIP);
52 }
53
54
55}
diff --git a/OpenSim/Services/Interfaces/IPresenceService.cs b/OpenSim/Services/Interfaces/IPresenceService.cs
index aa1c5bf..8d583ff 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
28using System;
28using OpenSim.Framework; 29using OpenSim.Framework;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
@@ -33,13 +34,40 @@ 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
40 public PresenceInfo()
41 {
42 }
43
44 public PresenceInfo(Dictionary<string, object> kvp)
45 {
46 if (kvp.ContainsKey("UserID"))
47 UserID = kvp["UserID"].ToString();
48 if (kvp.ContainsKey("RegionID"))
49 UUID.TryParse(kvp["RegionID"].ToString(), out RegionID);
50 }
51
52 public Dictionary<string, object> ToKeyValuePairs()
53 {
54 Dictionary<string, object> result = new Dictionary<string, object>();
55 result["UserID"] = UserID;
56 result["RegionID"] = RegionID.ToString();
57
58 return result;
59 }
39 } 60 }
40 61
41 public interface IPresenceService 62 public interface IPresenceService
42 { 63 {
43 bool Report(PresenceInfo presence); 64 bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID);
65 bool LogoutAgent(UUID sessionID);
66 bool LogoutRegionAgents(UUID regionID);
67
68 bool ReportAgent(UUID sessionID, UUID regionID);
69
70 PresenceInfo GetAgent(UUID sessionID);
71 PresenceInfo[] GetAgents(string[] userIDs);
44 } 72 }
45} 73}
diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs
index a169ab7..33d6fde 100644
--- a/OpenSim/Services/Interfaces/ISimulationService.cs
+++ b/OpenSim/Services/Interfaces/ISimulationService.cs
@@ -29,13 +29,18 @@ using System;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using OpenMetaverse; 30using OpenMetaverse;
31 31
32using GridRegion = OpenSim.Services.Interfaces.GridRegion;
33
32namespace OpenSim.Services.Interfaces 34namespace OpenSim.Services.Interfaces
33{ 35{
34 public interface ISimulationService 36 public interface ISimulationService
35 { 37 {
38 IScene GetScene(ulong regionHandle);
39 ISimulationService GetInnerService();
40
36 #region Agents 41 #region Agents
37 42
38 bool CreateAgent(ulong regionHandle, AgentCircuitData aCircuit, out string reason); 43 bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason);
39 44
40 /// <summary> 45 /// <summary>
41 /// Full child agent update. 46 /// Full child agent update.
@@ -43,7 +48,7 @@ namespace OpenSim.Services.Interfaces
43 /// <param name="regionHandle"></param> 48 /// <param name="regionHandle"></param>
44 /// <param name="data"></param> 49 /// <param name="data"></param>
45 /// <returns></returns> 50 /// <returns></returns>
46 bool UpdateAgent(ulong regionHandle, AgentData data); 51 bool UpdateAgent(GridRegion destination, AgentData data);
47 52
48 /// <summary> 53 /// <summary>
49 /// Short child agent update, mostly for position. 54 /// Short child agent update, mostly for position.
@@ -51,9 +56,9 @@ namespace OpenSim.Services.Interfaces
51 /// <param name="regionHandle"></param> 56 /// <param name="regionHandle"></param>
52 /// <param name="data"></param> 57 /// <param name="data"></param>
53 /// <returns></returns> 58 /// <returns></returns>
54 bool UpdateAgent(ulong regionHandle, AgentPosition data); 59 bool UpdateAgent(GridRegion destination, AgentPosition data);
55 60
56 bool RetrieveAgent(ulong regionHandle, UUID id, out IAgentData agent); 61 bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent);
57 62
58 /// <summary> 63 /// <summary>
59 /// Message from receiving region to departing region, telling it got contacted by the client. 64 /// Message from receiving region to departing region, telling it got contacted by the client.
@@ -63,7 +68,15 @@ namespace OpenSim.Services.Interfaces
63 /// <param name="id"></param> 68 /// <param name="id"></param>
64 /// <param name="uri"></param> 69 /// <param name="uri"></param>
65 /// <returns></returns> 70 /// <returns></returns>
66 bool ReleaseAgent(ulong regionHandle, UUID id, string uri); 71 bool ReleaseAgent(UUID originRegion, UUID id, string uri);
72
73 /// <summary>
74 /// Close child agent.
75 /// </summary>
76 /// <param name="regionHandle"></param>
77 /// <param name="id"></param>
78 /// <returns></returns>
79 bool CloseChildAgent(GridRegion destination, UUID id);
67 80
68 /// <summary> 81 /// <summary>
69 /// Close agent. 82 /// Close agent.
@@ -71,7 +84,7 @@ namespace OpenSim.Services.Interfaces
71 /// <param name="regionHandle"></param> 84 /// <param name="regionHandle"></param>
72 /// <param name="id"></param> 85 /// <param name="id"></param>
73 /// <returns></returns> 86 /// <returns></returns>
74 bool CloseAgent(ulong regionHandle, UUID id); 87 bool CloseAgent(GridRegion destination, UUID id);
75 88
76 #endregion Agents 89 #endregion Agents
77 90
@@ -84,7 +97,7 @@ namespace OpenSim.Services.Interfaces
84 /// <param name="sog"></param> 97 /// <param name="sog"></param>
85 /// <param name="isLocalCall"></param> 98 /// <param name="isLocalCall"></param>
86 /// <returns></returns> 99 /// <returns></returns>
87 bool CreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall); 100 bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall);
88 101
89 /// <summary> 102 /// <summary>
90 /// Create an object from the user's inventory in the destination region. 103 /// Create an object from the user's inventory in the destination region.
@@ -94,15 +107,9 @@ namespace OpenSim.Services.Interfaces
94 /// <param name="userID"></param> 107 /// <param name="userID"></param>
95 /// <param name="itemID"></param> 108 /// <param name="itemID"></param>
96 /// <returns></returns> 109 /// <returns></returns>
97 bool CreateObject(ulong regionHandle, UUID userID, UUID itemID); 110 bool CreateObject(GridRegion destination, UUID userID, UUID itemID);
98 111
99 #endregion Objects 112 #endregion Objects
100 113
101 #region Regions
102
103 bool HelloNeighbour(ulong regionHandle, RegionInfo thisRegion);
104
105 #endregion Regions
106
107 } 114 }
108} 115}
diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs
new file mode 100644
index 0000000..e316731
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IUserAccountService.cs
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31
32namespace OpenSim.Services.Interfaces
33{
34 public class UserAccount
35 {
36 public UserAccount()
37 {
38 }
39
40 public UserAccount(UUID principalID)
41 {
42 PrincipalID = principalID;
43 }
44
45 public UserAccount(UUID scopeID, string firstName, string lastName, string email)
46 {
47 PrincipalID = UUID.Random();
48 ScopeID = scopeID;
49 FirstName = firstName;
50 LastName = lastName;
51 Email = email;
52 ServiceURLs = new Dictionary<string, object>();
53 // Created = ???
54 }
55
56 public string FirstName;
57 public string LastName;
58 public string Email;
59 public UUID PrincipalID;
60 public UUID ScopeID;
61 public int UserLevel;
62 public int UserFlags;
63 public string UserTitle;
64
65 public Dictionary<string, object> ServiceURLs;
66
67 public int Created;
68
69 public string Name
70 {
71 get { return FirstName + " " + LastName; }
72 }
73
74 public UserAccount(Dictionary<string, object> kvp)
75 {
76 if (kvp.ContainsKey("FirstName"))
77 FirstName = kvp["FirstName"].ToString();
78 if (kvp.ContainsKey("LastName"))
79 LastName = kvp["LastName"].ToString();
80 if (kvp.ContainsKey("Email"))
81 Email = kvp["Email"].ToString();
82 if (kvp.ContainsKey("PrincipalID"))
83 UUID.TryParse(kvp["PrincipalID"].ToString(), out PrincipalID);
84 if (kvp.ContainsKey("ScopeID"))
85 UUID.TryParse(kvp["ScopeID"].ToString(), out ScopeID);
86 if (kvp.ContainsKey("UserLevel"))
87 UserLevel = Convert.ToInt32(kvp["UserLevel"].ToString());
88 if (kvp.ContainsKey("UserFlags"))
89 UserFlags = Convert.ToInt32(kvp["UserFlags"].ToString());
90 if (kvp.ContainsKey("UserTitle"))
91 UserTitle = kvp["UserTitle"].ToString();
92
93 if (kvp.ContainsKey("Created"))
94 Convert.ToInt32(kvp["Created"].ToString());
95 if (kvp.ContainsKey("ServiceURLs") && kvp["ServiceURLs"] != null)
96 {
97 ServiceURLs = new Dictionary<string, object>();
98 string str = kvp["ServiceURLs"].ToString();
99 if (str != string.Empty)
100 {
101 string[] parts = str.Split(new char[] { ';' });
102 Dictionary<string, object> dic = new Dictionary<string, object>();
103 foreach (string s in parts)
104 {
105 string[] parts2 = s.Split(new char[] { '*' });
106 if (parts2.Length == 2)
107 ServiceURLs[parts2[0]] = parts2[1];
108 }
109 }
110 }
111 }
112
113 public Dictionary<string, object> ToKeyValuePairs()
114 {
115 Dictionary<string, object> result = new Dictionary<string, object>();
116 result["FirstName"] = FirstName;
117 result["LastName"] = LastName;
118 result["Email"] = Email;
119 result["PrincipalID"] = PrincipalID.ToString();
120 result["ScopeID"] = ScopeID.ToString();
121 result["Created"] = Created.ToString();
122 result["UserLevel"] = UserLevel.ToString();
123 result["UserFlags"] = UserFlags.ToString();
124 result["UserTitle"] = UserTitle;
125
126 string str = string.Empty;
127 foreach (KeyValuePair<string, object> kvp in ServiceURLs)
128 {
129 str += kvp.Key + "*" + (kvp.Value == null ? "" : kvp.Value) + ";";
130 }
131 result["ServiceURLs"] = str;
132
133 return result;
134 }
135
136 };
137
138 public interface IUserAccountService
139 {
140 UserAccount GetUserAccount(UUID scopeID, UUID userID);
141 UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName);
142 UserAccount GetUserAccount(UUID scopeID, string Email);
143
144 /// <summary>
145 /// Returns the list of avatars that matches both the search criterion and the scope ID passed
146 /// </summary>
147 /// <param name="scopeID"></param>
148 /// <param name="query"></param>
149 /// <returns></returns>
150 List<UserAccount> GetUserAccounts(UUID scopeID, string query);
151
152 /// <summary>
153 /// Store the data given, wich replaces the stored data, therefore must be complete.
154 /// </summary>
155 /// <param name="data"></param>
156 /// <returns></returns>
157 bool StoreUserAccount(UserAccount data);
158 }
159}
diff --git a/OpenSim/Services/Interfaces/IUserService.cs b/OpenSim/Services/Interfaces/IUserService.cs
deleted file mode 100644
index 92bd8ef..0000000
--- a/OpenSim/Services/Interfaces/IUserService.cs
+++ /dev/null
@@ -1,103 +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
28using System.Collections.Generic;
29using OpenMetaverse;
30
31namespace OpenSim.Services.Interfaces
32{
33 public class UserAccount
34 {
35 public UserAccount()
36 {
37 }
38
39 public UserAccount(UUID userID, UUID homeRegionID, float homePositionX,
40 float homePositionY, float homePositionZ, float homeLookAtX,
41 float homeLookAtY, float homeLookAtZ)
42 {
43 UserID = userID;
44 HomeRegionID = homeRegionID;
45 HomePositionX = homePositionX;
46 HomePositionY = homePositionY;
47 HomePositionZ = homePositionZ;
48 HomeLookAtX = homeLookAtX;
49 HomeLookAtY = homeLookAtY;
50 HomeLookAtZ = homeLookAtZ;
51 }
52
53 public string FirstName;
54 public string LastName;
55 public UUID UserID;
56 public UUID ScopeID;
57
58 // For informational purposes only!
59 //
60 public string HomeRegionName;
61
62 public UUID HomeRegionID;
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
70 // These are here because they
71 // concern the account rather than
72 // the profile. They just happen to
73 // be used in the Linden profile as well
74 //
75 public int GodLevel;
76 public int UserFlags;
77 public string AccountType;
78
79 };
80
81 public interface IUserAccountService
82 {
83 UserAccount GetUserAccount(UUID scopeID, UUID userID);
84 UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName);
85 // Returns the list of avatars that matches both the search
86 // criterion and the scope ID passed
87 //
88 List<UserAccount> GetUserAccount(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
96 // Update all updatable fields
97 //
98 bool SetUserAccount(UserAccount data, UUID PrincipalID, string token);
99
100 // Creates a user data record
101 bool CreateUserAccount(UserAccount data, UUID PrincipalID, string token);
102 }
103}
diff --git a/OpenSim/Services/InventoryService/HGInventoryService.cs b/OpenSim/Services/InventoryService/HGInventoryService.cs
new file mode 100644
index 0000000..061effe
--- /dev/null
+++ b/OpenSim/Services/InventoryService/HGInventoryService.cs
@@ -0,0 +1,302 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using log4net;
32using Nini.Config;
33using System.Reflection;
34using OpenSim.Services.Base;
35using OpenSim.Services.Interfaces;
36using OpenSim.Data;
37using OpenSim.Framework;
38
39namespace OpenSim.Services.InventoryService
40{
41 public class HGInventoryService : XInventoryService, IInventoryService
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
46
47 protected IXInventoryData m_Database;
48
49 public HGInventoryService(IConfigSource config)
50 : base(config)
51 {
52 string dllName = String.Empty;
53 string connString = String.Empty;
54 //string realm = "Inventory"; // OSG version doesn't use this
55
56 //
57 // Try reading the [DatabaseService] section, if it exists
58 //
59 IConfig dbConfig = config.Configs["DatabaseService"];
60 if (dbConfig != null)
61 {
62 if (dllName == String.Empty)
63 dllName = dbConfig.GetString("StorageProvider", String.Empty);
64 if (connString == String.Empty)
65 connString = dbConfig.GetString("ConnectionString", String.Empty);
66 }
67
68 //
69 // Try reading the [InventoryService] section, if it exists
70 //
71 IConfig authConfig = config.Configs["InventoryService"];
72 if (authConfig != null)
73 {
74 dllName = authConfig.GetString("StorageProvider", dllName);
75 connString = authConfig.GetString("ConnectionString", connString);
76 // realm = authConfig.GetString("Realm", realm);
77 }
78
79 //
80 // We tried, but this doesn't exist. We can't proceed.
81 //
82 if (dllName == String.Empty)
83 throw new Exception("No StorageProvider configured");
84
85 m_Database = LoadPlugin<IXInventoryData>(dllName,
86 new Object[] {connString, String.Empty});
87 if (m_Database == null)
88 throw new Exception("Could not find a storage interface in the given module");
89
90 m_log.Debug("[HG INVENTORY SERVICE]: Starting...");
91 }
92
93 public override bool CreateUserInventory(UUID principalID)
94 {
95 // NOGO
96 return false;
97 }
98
99
100 public override List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
101 {
102 // NOGO for this inventory service
103 return new List<InventoryFolderBase>();
104 }
105
106 public override InventoryFolderBase GetRootFolder(UUID principalID)
107 {
108 // Warp! Root folder for travelers
109 XInventoryFolder[] folders = m_Database.GetFolders(
110 new string[] { "agentID", "folderName"},
111 new string[] { principalID.ToString(), "Suitcase" });
112
113 if (folders.Length > 0)
114 return ConvertToOpenSim(folders[0]);
115
116 // make one
117 XInventoryFolder suitcase = CreateFolder(principalID, UUID.Zero, (int)AssetType.Folder, "Suitcase");
118 return ConvertToOpenSim(suitcase);
119 }
120
121 //private bool CreateSystemFolders(UUID principalID, XInventoryFolder suitcase)
122 //{
123
124 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Animation, "Animations");
125 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Bodypart, "Body Parts");
126 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.CallingCard, "Calling Cards");
127 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Clothing, "Clothing");
128 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Gesture, "Gestures");
129 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Landmark, "Landmarks");
130 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.LostAndFoundFolder, "Lost And Found");
131 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Notecard, "Notecards");
132 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Object, "Objects");
133 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.SnapshotFolder, "Photo Album");
134 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.LSLText, "Scripts");
135 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Sound, "Sounds");
136 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Texture, "Textures");
137 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.TrashFolder, "Trash");
138
139 // return true;
140 //}
141
142
143 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
144 {
145 return GetRootFolder(principalID);
146 }
147
148 //
149 // Use the inherited methods
150 //
151 //public InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
152 //{
153 //}
154
155 //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
156 //{
157 //}
158
159 //public override bool AddFolder(InventoryFolderBase folder)
160 //{
161 // // Check if it's under the Suitcase folder
162 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner);
163 // InventoryFolderBase suitcase = GetRootFolder(folder.Owner);
164 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
165
166 // foreach (InventoryFolderBase f in suitDescendents)
167 // if (folder.ParentID == f.ID)
168 // {
169 // XInventoryFolder xFolder = ConvertFromOpenSim(folder);
170 // return m_Database.StoreFolder(xFolder);
171 // }
172 // return false;
173 //}
174
175 private List<InventoryFolderBase> GetDescendents(List<InventoryFolderBase> lst, UUID root)
176 {
177 List<InventoryFolderBase> direct = lst.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == root; });
178 if (direct == null)
179 return new List<InventoryFolderBase>();
180
181 List<InventoryFolderBase> indirect = new List<InventoryFolderBase>();
182 foreach (InventoryFolderBase f in direct)
183 indirect.AddRange(GetDescendents(lst, f.ID));
184
185 direct.AddRange(indirect);
186 return direct;
187 }
188
189 // Use inherited method
190 //public bool UpdateFolder(InventoryFolderBase folder)
191 //{
192 //}
193
194 //public override bool MoveFolder(InventoryFolderBase folder)
195 //{
196 // XInventoryFolder[] x = m_Database.GetFolders(
197 // new string[] { "folderID" },
198 // new string[] { folder.ID.ToString() });
199
200 // if (x.Length == 0)
201 // return false;
202
203 // // Check if it's under the Suitcase folder
204 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner);
205 // InventoryFolderBase suitcase = GetRootFolder(folder.Owner);
206 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
207
208 // foreach (InventoryFolderBase f in suitDescendents)
209 // if (folder.ParentID == f.ID)
210 // {
211 // x[0].parentFolderID = folder.ParentID;
212 // return m_Database.StoreFolder(x[0]);
213 // }
214
215 // return false;
216 //}
217
218 public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
219 {
220 // NOGO
221 return false;
222 }
223
224 public override bool PurgeFolder(InventoryFolderBase folder)
225 {
226 // NOGO
227 return false;
228 }
229
230 // Unfortunately we need to use the inherited method because of how DeRez works.
231 // The viewer sends the folderID hard-wired in the derez message
232 //public override bool AddItem(InventoryItemBase item)
233 //{
234 // // Check if it's under the Suitcase folder
235 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner);
236 // InventoryFolderBase suitcase = GetRootFolder(item.Owner);
237 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
238
239 // foreach (InventoryFolderBase f in suitDescendents)
240 // if (item.Folder == f.ID)
241 // return m_Database.StoreItem(ConvertFromOpenSim(item));
242
243 // return false;
244 //}
245
246 //public override bool UpdateItem(InventoryItemBase item)
247 //{
248 // // Check if it's under the Suitcase folder
249 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner);
250 // InventoryFolderBase suitcase = GetRootFolder(item.Owner);
251 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
252
253 // foreach (InventoryFolderBase f in suitDescendents)
254 // if (item.Folder == f.ID)
255 // return m_Database.StoreItem(ConvertFromOpenSim(item));
256
257 // return false;
258 //}
259
260 //public override bool MoveItems(UUID principalID, List<InventoryItemBase> items)
261 //{
262 // // Principal is b0rked. *sigh*
263 // //
264 // // Let's assume they all have the same principal
265 // // Check if it's under the Suitcase folder
266 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(items[0].Owner);
267 // InventoryFolderBase suitcase = GetRootFolder(items[0].Owner);
268 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
269
270 // foreach (InventoryItemBase i in items)
271 // {
272 // foreach (InventoryFolderBase f in suitDescendents)
273 // if (i.Folder == f.ID)
274 // m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString());
275 // }
276
277 // return true;
278 //}
279
280 // Let these pass. Use inherited methods.
281 //public bool DeleteItems(UUID principalID, List<UUID> itemIDs)
282 //{
283 //}
284
285 //public InventoryItemBase GetItem(InventoryItemBase item)
286 //{
287 //}
288
289 //public InventoryFolderBase GetFolder(InventoryFolderBase folder)
290 //{
291 //}
292
293 //public List<InventoryItemBase> GetActiveGestures(UUID principalID)
294 //{
295 //}
296
297 //public int GetAssetPermissions(UUID principalID, UUID assetID)
298 //{
299 //}
300
301 }
302}
diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs
index 95007f1..fbcd663 100644
--- a/OpenSim/Services/InventoryService/InventoryService.cs
+++ b/OpenSim/Services/InventoryService/InventoryService.cs
@@ -66,6 +66,7 @@ namespace OpenSim.Services.InventoryService
66 // Agent has no inventory structure yet. 66 // Agent has no inventory structure yet.
67 if (null == rootFolder) 67 if (null == rootFolder)
68 { 68 {
69 m_log.DebugFormat("[INVENTORY SERVICE]: No root folder");
69 return null; 70 return null;
70 } 71 }
71 72
@@ -108,7 +109,7 @@ namespace OpenSim.Services.InventoryService
108 { 109 {
109 existingRootFolder = GetRootFolder(user); 110 existingRootFolder = GetRootFolder(user);
110 } 111 }
111 catch (Exception e) 112 catch /*(Exception e)*/
112 { 113 {
113 // Munch the exception, it has already been reported 114 // Munch the exception, it has already been reported
114 // 115 //
@@ -298,6 +299,7 @@ namespace OpenSim.Services.InventoryService
298 if ((folder.Type != (short)AssetType.Folder) && (folder.Type != (short)AssetType.Unknown)) 299 if ((folder.Type != (short)AssetType.Folder) && (folder.Type != (short)AssetType.Unknown))
299 folders[(AssetType)folder.Type] = folder; 300 folders[(AssetType)folder.Type] = folder;
300 } 301 }
302 m_log.DebugFormat("[INVENTORY SERVICE]: Got {0} system folders for {1}", folders.Count, userID);
301 return folders; 303 return folders;
302 } 304 }
303 } 305 }
diff --git a/OpenSim/Services/InventoryService/LibraryService.cs b/OpenSim/Services/InventoryService/LibraryService.cs
new file mode 100644
index 0000000..383f311
--- /dev/null
+++ b/OpenSim/Services/InventoryService/LibraryService.cs
@@ -0,0 +1,283 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Xml;
33
34using OpenSim.Framework;
35using OpenSim.Services.Base;
36using OpenSim.Services.Interfaces;
37
38using log4net;
39using Nini.Config;
40using OpenMetaverse;
41
42namespace OpenSim.Services.InventoryService
43{
44 /// <summary>
45 /// Basically a hack to give us a Inventory library while we don't have a inventory server
46 /// once the server is fully implemented then should read the data from that
47 /// </summary>
48 public class LibraryService : ServiceBase, ILibraryService
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private InventoryFolderImpl m_LibraryRootFolder;
53
54 public InventoryFolderImpl LibraryRootFolder
55 {
56 get { return m_LibraryRootFolder; }
57 }
58
59 private UUID libOwner = new UUID("11111111-1111-0000-0000-000100bba000");
60
61 /// <summary>
62 /// Holds the root library folder and all its descendents. This is really only used during inventory
63 /// setup so that we don't have to repeatedly search the tree of library folders.
64 /// </summary>
65 protected Dictionary<UUID, InventoryFolderImpl> libraryFolders
66 = new Dictionary<UUID, InventoryFolderImpl>();
67
68 public LibraryService(IConfigSource config)
69 : base(config)
70 {
71 string pLibrariesLocation = Path.Combine("inventory", "Libraries.xml");
72 string pLibName = "OpenSim Library";
73
74 IConfig libConfig = config.Configs["LibraryService"];
75 if (libConfig != null)
76 {
77 pLibrariesLocation = libConfig.GetString("DefaultLibrary", pLibrariesLocation);
78 pLibName = libConfig.GetString("LibraryName", pLibName);
79 }
80
81 m_log.Debug("[LIBRARY]: Starting library service...");
82
83 m_LibraryRootFolder = new InventoryFolderImpl();
84 m_LibraryRootFolder.Owner = libOwner;
85 m_LibraryRootFolder.ID = new UUID("00000112-000f-0000-0000-000100bba000");
86 m_LibraryRootFolder.Name = pLibName;
87 m_LibraryRootFolder.ParentID = UUID.Zero;
88 m_LibraryRootFolder.Type = (short)8;
89 m_LibraryRootFolder.Version = (ushort)1;
90
91 libraryFolders.Add(m_LibraryRootFolder.ID, m_LibraryRootFolder);
92
93 LoadLibraries(pLibrariesLocation);
94 }
95
96 public InventoryItemBase CreateItem(UUID inventoryID, UUID assetID, string name, string description,
97 int assetType, int invType, UUID parentFolderID)
98 {
99 InventoryItemBase item = new InventoryItemBase();
100 item.Owner = libOwner;
101 item.CreatorId = libOwner.ToString();
102 item.ID = inventoryID;
103 item.AssetID = assetID;
104 item.Description = description;
105 item.Name = name;
106 item.AssetType = assetType;
107 item.InvType = invType;
108 item.Folder = parentFolderID;
109 item.BasePermissions = 0x7FFFFFFF;
110 item.EveryOnePermissions = 0x7FFFFFFF;
111 item.CurrentPermissions = 0x7FFFFFFF;
112 item.NextPermissions = 0x7FFFFFFF;
113 return item;
114 }
115
116 /// <summary>
117 /// Use the asset set information at path to load assets
118 /// </summary>
119 /// <param name="path"></param>
120 /// <param name="assets"></param>
121 protected void LoadLibraries(string librariesControlPath)
122 {
123 m_log.InfoFormat("[LIBRARY INVENTORY]: Loading library control file {0}", librariesControlPath);
124 LoadFromFile(librariesControlPath, "Libraries control", ReadLibraryFromConfig);
125 }
126
127 /// <summary>
128 /// Read a library set from config
129 /// </summary>
130 /// <param name="config"></param>
131 protected void ReadLibraryFromConfig(IConfig config, string path)
132 {
133 string basePath = Path.GetDirectoryName(path);
134 string foldersPath
135 = Path.Combine(
136 basePath, config.GetString("foldersFile", String.Empty));
137
138 LoadFromFile(foldersPath, "Library folders", ReadFolderFromConfig);
139
140 string itemsPath
141 = Path.Combine(
142 basePath, config.GetString("itemsFile", String.Empty));
143
144 LoadFromFile(itemsPath, "Library items", ReadItemFromConfig);
145 }
146
147 /// <summary>
148 /// Read a library inventory folder from a loaded configuration
149 /// </summary>
150 /// <param name="source"></param>
151 private void ReadFolderFromConfig(IConfig config, string path)
152 {
153 InventoryFolderImpl folderInfo = new InventoryFolderImpl();
154
155 folderInfo.ID = new UUID(config.GetString("folderID", m_LibraryRootFolder.ID.ToString()));
156 folderInfo.Name = config.GetString("name", "unknown");
157 folderInfo.ParentID = new UUID(config.GetString("parentFolderID", m_LibraryRootFolder.ID.ToString()));
158 folderInfo.Type = (short)config.GetInt("type", 8);
159
160 folderInfo.Owner = libOwner;
161 folderInfo.Version = 1;
162
163 if (libraryFolders.ContainsKey(folderInfo.ParentID))
164 {
165 InventoryFolderImpl parentFolder = libraryFolders[folderInfo.ParentID];
166
167 libraryFolders.Add(folderInfo.ID, folderInfo);
168 parentFolder.AddChildFolder(folderInfo);
169
170// m_log.InfoFormat("[LIBRARY INVENTORY]: Adding folder {0} ({1})", folderInfo.name, folderInfo.folderID);
171 }
172 else
173 {
174 m_log.WarnFormat(
175 "[LIBRARY INVENTORY]: Couldn't add folder {0} ({1}) since parent folder with ID {2} does not exist!",
176 folderInfo.Name, folderInfo.ID, folderInfo.ParentID);
177 }
178 }
179
180 /// <summary>
181 /// Read a library inventory item metadata from a loaded configuration
182 /// </summary>
183 /// <param name="source"></param>
184 private void ReadItemFromConfig(IConfig config, string path)
185 {
186 InventoryItemBase item = new InventoryItemBase();
187 item.Owner = libOwner;
188 item.CreatorId = libOwner.ToString();
189 item.ID = new UUID(config.GetString("inventoryID", m_LibraryRootFolder.ID.ToString()));
190 item.AssetID = new UUID(config.GetString("assetID", item.ID.ToString()));
191 item.Folder = new UUID(config.GetString("folderID", m_LibraryRootFolder.ID.ToString()));
192 item.Name = config.GetString("name", String.Empty);
193 item.Description = config.GetString("description", item.Name);
194 item.InvType = config.GetInt("inventoryType", 0);
195 item.AssetType = config.GetInt("assetType", item.InvType);
196 item.CurrentPermissions = (uint)config.GetLong("currentPermissions", 0x7FFFFFFF);
197 item.NextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF);
198 item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF);
199 item.BasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF);
200 item.Flags = (uint)config.GetInt("flags", 0);
201
202 if (libraryFolders.ContainsKey(item.Folder))
203 {
204 InventoryFolderImpl parentFolder = libraryFolders[item.Folder];
205 try
206 {
207 parentFolder.Items.Add(item.ID, item);
208 }
209 catch (Exception)
210 {
211 m_log.WarnFormat("[LIBRARY INVENTORY] Item {1} [{0}] not added, duplicate item", item.ID, item.Name);
212 }
213 }
214 else
215 {
216 m_log.WarnFormat(
217 "[LIBRARY INVENTORY]: Couldn't add item {0} ({1}) since parent folder with ID {2} does not exist!",
218 item.Name, item.ID, item.Folder);
219 }
220 }
221
222 private delegate void ConfigAction(IConfig config, string path);
223
224 /// <summary>
225 /// Load the given configuration at a path and perform an action on each Config contained within it
226 /// </summary>
227 /// <param name="path"></param>
228 /// <param name="fileDescription"></param>
229 /// <param name="action"></param>
230 private static void LoadFromFile(string path, string fileDescription, ConfigAction action)
231 {
232 if (File.Exists(path))
233 {
234 try
235 {
236 XmlConfigSource source = new XmlConfigSource(path);
237
238 for (int i = 0; i < source.Configs.Count; i++)
239 {
240 action(source.Configs[i], path);
241 }
242 }
243 catch (XmlException e)
244 {
245 m_log.ErrorFormat("[LIBRARY INVENTORY]: Error loading {0} : {1}", path, e);
246 }
247 }
248 else
249 {
250 m_log.ErrorFormat("[LIBRARY INVENTORY]: {0} file {1} does not exist!", fileDescription, path);
251 }
252 }
253
254 /// <summary>
255 /// Looks like a simple getter, but is written like this for some consistency with the other Request
256 /// methods in the superclass
257 /// </summary>
258 /// <returns></returns>
259 public Dictionary<UUID, InventoryFolderImpl> GetAllFolders()
260 {
261 Dictionary<UUID, InventoryFolderImpl> fs = new Dictionary<UUID, InventoryFolderImpl>();
262 fs.Add(m_LibraryRootFolder.ID, m_LibraryRootFolder);
263 List<InventoryFolderImpl> fis = TraverseFolder(m_LibraryRootFolder);
264 foreach (InventoryFolderImpl f in fis)
265 {
266 fs.Add(f.ID, f);
267 }
268 //return libraryFolders;
269 return fs;
270 }
271
272 private List<InventoryFolderImpl> TraverseFolder(InventoryFolderImpl node)
273 {
274 List<InventoryFolderImpl> folders = node.RequestListOfFolderImpls();
275 List<InventoryFolderImpl> subs = new List<InventoryFolderImpl>();
276 foreach (InventoryFolderImpl f in folders)
277 subs.AddRange(TraverseFolder(f));
278
279 folders.AddRange(subs);
280 return folders;
281 }
282 }
283}
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 2c79c77..974caf0 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -87,7 +87,7 @@ namespace OpenSim.Services.InventoryService
87 throw new Exception("Could not find a storage interface in the given module"); 87 throw new Exception("Could not find a storage interface in the given module");
88 } 88 }
89 89
90 public bool CreateUserInventory(UUID principalID) 90 public virtual bool CreateUserInventory(UUID principalID)
91 { 91 {
92 // This is braindeaad. We can't ever communicate that we fixed 92 // This is braindeaad. We can't ever communicate that we fixed
93 // an existing inventory. Well, just return root folder status, 93 // an existing inventory. Well, just return root folder status,
@@ -99,7 +99,7 @@ namespace OpenSim.Services.InventoryService
99 99
100 if (rootFolder == null) 100 if (rootFolder == null)
101 { 101 {
102 rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)AssetType.Folder, "My Inventory")); 102 rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)AssetType.RootFolder, "My Inventory"));
103 result = true; 103 result = true;
104 } 104 }
105 105
@@ -137,7 +137,7 @@ namespace OpenSim.Services.InventoryService
137 return result; 137 return result;
138 } 138 }
139 139
140 private XInventoryFolder CreateFolder(UUID principalID, UUID parentID, int type, string name) 140 protected XInventoryFolder CreateFolder(UUID principalID, UUID parentID, int type, string name)
141 { 141 {
142 XInventoryFolder newFolder = new XInventoryFolder(); 142 XInventoryFolder newFolder = new XInventoryFolder();
143 143
@@ -153,7 +153,7 @@ namespace OpenSim.Services.InventoryService
153 return newFolder; 153 return newFolder;
154 } 154 }
155 155
156 private XInventoryFolder[] GetSystemFolders(UUID principalID) 156 protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID)
157 { 157 {
158 XInventoryFolder[] allFolders = m_Database.GetFolders( 158 XInventoryFolder[] allFolders = m_Database.GetFolders(
159 new string[] { "agentID" }, 159 new string[] { "agentID" },
@@ -171,7 +171,7 @@ namespace OpenSim.Services.InventoryService
171 return sysFolders; 171 return sysFolders;
172 } 172 }
173 173
174 public List<InventoryFolderBase> GetInventorySkeleton(UUID principalID) 174 public virtual List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
175 { 175 {
176 XInventoryFolder[] allFolders = m_Database.GetFolders( 176 XInventoryFolder[] allFolders = m_Database.GetFolders(
177 new string[] { "agentID" }, 177 new string[] { "agentID" },
@@ -184,14 +184,14 @@ namespace OpenSim.Services.InventoryService
184 184
185 foreach (XInventoryFolder x in allFolders) 185 foreach (XInventoryFolder x in allFolders)
186 { 186 {
187 m_log.DebugFormat("[INVENTORY]: Adding folder {0} to skeleton", x.folderName); 187 //m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to skeleton", x.folderName);
188 folders.Add(ConvertToOpenSim(x)); 188 folders.Add(ConvertToOpenSim(x));
189 } 189 }
190 190
191 return folders; 191 return folders;
192 } 192 }
193 193
194 public InventoryFolderBase GetRootFolder(UUID principalID) 194 public virtual InventoryFolderBase GetRootFolder(UUID principalID)
195 { 195 {
196 XInventoryFolder[] folders = m_Database.GetFolders( 196 XInventoryFolder[] folders = m_Database.GetFolders(
197 new string[] { "agentID", "parentFolderID"}, 197 new string[] { "agentID", "parentFolderID"},
@@ -203,7 +203,7 @@ namespace OpenSim.Services.InventoryService
203 return ConvertToOpenSim(folders[0]); 203 return ConvertToOpenSim(folders[0]);
204 } 204 }
205 205
206 public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 206 public virtual InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
207 { 207 {
208 XInventoryFolder[] folders = m_Database.GetFolders( 208 XInventoryFolder[] folders = m_Database.GetFolders(
209 new string[] { "agentID", "type"}, 209 new string[] { "agentID", "type"},
@@ -215,13 +215,13 @@ namespace OpenSim.Services.InventoryService
215 return ConvertToOpenSim(folders[0]); 215 return ConvertToOpenSim(folders[0]);
216 } 216 }
217 217
218 public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) 218 public virtual InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
219 { 219 {
220 // This method doesn't receive a valud principal id from the 220 // This method doesn't receive a valud principal id from the
221 // connector. So we disregard the principal and look 221 // connector. So we disregard the principal and look
222 // by ID. 222 // by ID.
223 // 223 //
224 m_log.DebugFormat("[INVENTORY]: Fetch contents for folder {0}", folderID.ToString()); 224 m_log.DebugFormat("[XINVENTORY]: Fetch contents for folder {0}", folderID.ToString());
225 InventoryCollection inventory = new InventoryCollection(); 225 InventoryCollection inventory = new InventoryCollection();
226 inventory.UserID = principalID; 226 inventory.UserID = principalID;
227 inventory.Folders = new List<InventoryFolderBase>(); 227 inventory.Folders = new List<InventoryFolderBase>();
@@ -233,7 +233,7 @@ namespace OpenSim.Services.InventoryService
233 233
234 foreach (XInventoryFolder x in folders) 234 foreach (XInventoryFolder x in folders)
235 { 235 {
236 m_log.DebugFormat("[INVENTORY]: Adding folder {0} to response", x.folderName); 236 //m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to response", x.folderName);
237 inventory.Folders.Add(ConvertToOpenSim(x)); 237 inventory.Folders.Add(ConvertToOpenSim(x));
238 } 238 }
239 239
@@ -243,14 +243,14 @@ namespace OpenSim.Services.InventoryService
243 243
244 foreach (XInventoryItem i in items) 244 foreach (XInventoryItem i in items)
245 { 245 {
246 m_log.DebugFormat("[INVENTORY]: Adding item {0} to response", i.inventoryName); 246 //m_log.DebugFormat("[XINVENTORY]: Adding item {0} to response", i.inventoryName);
247 inventory.Items.Add(ConvertToOpenSim(i)); 247 inventory.Items.Add(ConvertToOpenSim(i));
248 } 248 }
249 249
250 return inventory; 250 return inventory;
251 } 251 }
252 252
253 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 253 public virtual List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
254 { 254 {
255 // Since we probably don't get a valid principal here, either ... 255 // Since we probably don't get a valid principal here, either ...
256 // 256 //
@@ -266,18 +266,18 @@ namespace OpenSim.Services.InventoryService
266 return invItems; 266 return invItems;
267 } 267 }
268 268
269 public bool AddFolder(InventoryFolderBase folder) 269 public virtual bool AddFolder(InventoryFolderBase folder)
270 { 270 {
271 XInventoryFolder xFolder = ConvertFromOpenSim(folder); 271 XInventoryFolder xFolder = ConvertFromOpenSim(folder);
272 return m_Database.StoreFolder(xFolder); 272 return m_Database.StoreFolder(xFolder);
273 } 273 }
274 274
275 public bool UpdateFolder(InventoryFolderBase folder) 275 public virtual bool UpdateFolder(InventoryFolderBase folder)
276 { 276 {
277 return AddFolder(folder); 277 return AddFolder(folder);
278 } 278 }
279 279
280 public bool MoveFolder(InventoryFolderBase folder) 280 public virtual bool MoveFolder(InventoryFolderBase folder)
281 { 281 {
282 XInventoryFolder[] x = m_Database.GetFolders( 282 XInventoryFolder[] x = m_Database.GetFolders(
283 new string[] { "folderID" }, 283 new string[] { "folderID" },
@@ -293,7 +293,7 @@ namespace OpenSim.Services.InventoryService
293 293
294 // We don't check the principal's ID here 294 // We don't check the principal's ID here
295 // 295 //
296 public bool DeleteFolders(UUID principalID, List<UUID> folderIDs) 296 public virtual bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
297 { 297 {
298 // Ignore principal ID, it's bogus at connector level 298 // Ignore principal ID, it's bogus at connector level
299 // 299 //
@@ -308,7 +308,7 @@ namespace OpenSim.Services.InventoryService
308 return true; 308 return true;
309 } 309 }
310 310
311 public bool PurgeFolder(InventoryFolderBase folder) 311 public virtual bool PurgeFolder(InventoryFolderBase folder)
312 { 312 {
313 XInventoryFolder[] subFolders = m_Database.GetFolders( 313 XInventoryFolder[] subFolders = m_Database.GetFolders(
314 new string[] { "parentFolderID" }, 314 new string[] { "parentFolderID" },
@@ -325,17 +325,17 @@ namespace OpenSim.Services.InventoryService
325 return true; 325 return true;
326 } 326 }
327 327
328 public bool AddItem(InventoryItemBase item) 328 public virtual bool AddItem(InventoryItemBase item)
329 { 329 {
330 return m_Database.StoreItem(ConvertFromOpenSim(item)); 330 return m_Database.StoreItem(ConvertFromOpenSim(item));
331 } 331 }
332 332
333 public bool UpdateItem(InventoryItemBase item) 333 public virtual bool UpdateItem(InventoryItemBase item)
334 { 334 {
335 return m_Database.StoreItem(ConvertFromOpenSim(item)); 335 return m_Database.StoreItem(ConvertFromOpenSim(item));
336 } 336 }
337 337
338 public bool MoveItems(UUID principalID, List<InventoryItemBase> items) 338 public virtual bool MoveItems(UUID principalID, List<InventoryItemBase> items)
339 { 339 {
340 // Principal is b0rked. *sigh* 340 // Principal is b0rked. *sigh*
341 // 341 //
@@ -347,7 +347,7 @@ namespace OpenSim.Services.InventoryService
347 return true; 347 return true;
348 } 348 }
349 349
350 public bool DeleteItems(UUID principalID, List<UUID> itemIDs) 350 public virtual bool DeleteItems(UUID principalID, List<UUID> itemIDs)
351 { 351 {
352 // Just use the ID... *facepalms* 352 // Just use the ID... *facepalms*
353 // 353 //
@@ -357,7 +357,7 @@ namespace OpenSim.Services.InventoryService
357 return true; 357 return true;
358 } 358 }
359 359
360 public InventoryItemBase GetItem(InventoryItemBase item) 360 public virtual InventoryItemBase GetItem(InventoryItemBase item)
361 { 361 {
362 XInventoryItem[] items = m_Database.GetItems( 362 XInventoryItem[] items = m_Database.GetItems(
363 new string[] { "inventoryID" }, 363 new string[] { "inventoryID" },
@@ -369,7 +369,7 @@ namespace OpenSim.Services.InventoryService
369 return ConvertToOpenSim(items[0]); 369 return ConvertToOpenSim(items[0]);
370 } 370 }
371 371
372 public InventoryFolderBase GetFolder(InventoryFolderBase folder) 372 public virtual InventoryFolderBase GetFolder(InventoryFolderBase folder)
373 { 373 {
374 XInventoryFolder[] folders = m_Database.GetFolders( 374 XInventoryFolder[] folders = m_Database.GetFolders(
375 new string[] { "folderID"}, 375 new string[] { "folderID"},
@@ -381,12 +381,12 @@ namespace OpenSim.Services.InventoryService
381 return ConvertToOpenSim(folders[0]); 381 return ConvertToOpenSim(folders[0]);
382 } 382 }
383 383
384 public List<InventoryItemBase> GetActiveGestures(UUID principalID) 384 public virtual List<InventoryItemBase> GetActiveGestures(UUID principalID)
385 { 385 {
386 XInventoryItem[] items = m_Database.GetActiveGestures(principalID); 386 XInventoryItem[] items = m_Database.GetActiveGestures(principalID);
387 387
388 if (items.Length == 0) 388 if (items.Length == 0)
389 return null; 389 return new List<InventoryItemBase>();
390 390
391 List<InventoryItemBase> ret = new List<InventoryItemBase>(); 391 List<InventoryItemBase> ret = new List<InventoryItemBase>();
392 392
@@ -396,7 +396,7 @@ namespace OpenSim.Services.InventoryService
396 return ret; 396 return ret;
397 } 397 }
398 398
399 public int GetAssetPermissions(UUID principalID, UUID assetID) 399 public virtual int GetAssetPermissions(UUID principalID, UUID assetID)
400 { 400 {
401 return m_Database.GetAssetPermissions(principalID, assetID); 401 return m_Database.GetAssetPermissions(principalID, assetID);
402 } 402 }
@@ -421,7 +421,7 @@ namespace OpenSim.Services.InventoryService
421 421
422 // CM Helpers 422 // CM Helpers
423 // 423 //
424 private InventoryFolderBase ConvertToOpenSim(XInventoryFolder folder) 424 protected InventoryFolderBase ConvertToOpenSim(XInventoryFolder folder)
425 { 425 {
426 InventoryFolderBase newFolder = new InventoryFolderBase(); 426 InventoryFolderBase newFolder = new InventoryFolderBase();
427 427
@@ -435,7 +435,7 @@ namespace OpenSim.Services.InventoryService
435 return newFolder; 435 return newFolder;
436 } 436 }
437 437
438 private XInventoryFolder ConvertFromOpenSim(InventoryFolderBase folder) 438 protected XInventoryFolder ConvertFromOpenSim(InventoryFolderBase folder)
439 { 439 {
440 XInventoryFolder newFolder = new XInventoryFolder(); 440 XInventoryFolder newFolder = new XInventoryFolder();
441 441
@@ -449,7 +449,7 @@ namespace OpenSim.Services.InventoryService
449 return newFolder; 449 return newFolder;
450 } 450 }
451 451
452 private InventoryItemBase ConvertToOpenSim(XInventoryItem item) 452 protected InventoryItemBase ConvertToOpenSim(XInventoryItem item)
453 { 453 {
454 InventoryItemBase newItem = new InventoryItemBase(); 454 InventoryItemBase newItem = new InventoryItemBase();
455 455
@@ -468,7 +468,10 @@ namespace OpenSim.Services.InventoryService
468 newItem.EveryOnePermissions = (uint)item.inventoryEveryOnePermissions; 468 newItem.EveryOnePermissions = (uint)item.inventoryEveryOnePermissions;
469 newItem.GroupPermissions = (uint)item.inventoryGroupPermissions; 469 newItem.GroupPermissions = (uint)item.inventoryGroupPermissions;
470 newItem.GroupID = item.groupID; 470 newItem.GroupID = item.groupID;
471 newItem.GroupOwned = item.groupOwned; 471 if (item.groupOwned == 0)
472 newItem.GroupOwned = false;
473 else
474 newItem.GroupOwned = true;
472 newItem.SalePrice = item.salePrice; 475 newItem.SalePrice = item.salePrice;
473 newItem.SaleType = (byte)item.saleType; 476 newItem.SaleType = (byte)item.saleType;
474 newItem.Flags = (uint)item.flags; 477 newItem.Flags = (uint)item.flags;
@@ -477,7 +480,7 @@ namespace OpenSim.Services.InventoryService
477 return newItem; 480 return newItem;
478 } 481 }
479 482
480 private XInventoryItem ConvertFromOpenSim(InventoryItemBase item) 483 protected XInventoryItem ConvertFromOpenSim(InventoryItemBase item)
481 { 484 {
482 XInventoryItem newItem = new XInventoryItem(); 485 XInventoryItem newItem = new XInventoryItem();
483 486
@@ -496,7 +499,10 @@ namespace OpenSim.Services.InventoryService
496 newItem.inventoryEveryOnePermissions = (int)item.EveryOnePermissions; 499 newItem.inventoryEveryOnePermissions = (int)item.EveryOnePermissions;
497 newItem.inventoryGroupPermissions = (int)item.GroupPermissions; 500 newItem.inventoryGroupPermissions = (int)item.GroupPermissions;
498 newItem.groupID = item.GroupID; 501 newItem.groupID = item.GroupID;
499 newItem.groupOwned = item.GroupOwned; 502 if (item.GroupOwned)
503 newItem.groupOwned = 1;
504 else
505 newItem.groupOwned = 0;
500 newItem.salePrice = item.SalePrice; 506 newItem.salePrice = item.SalePrice;
501 newItem.saleType = (int)item.SaleType; 507 newItem.saleType = (int)item.SaleType;
502 newItem.flags = (int)item.Flags; 508 newItem.flags = (int)item.Flags;
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
new file mode 100644
index 0000000..edf41bc
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -0,0 +1,995 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using OpenSim.Framework;
35using OpenSim.Framework.Capabilities;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
39
40using log4net;
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
43using OSDArray = OpenMetaverse.StructuredData.OSDArray;
44using OSDMap = OpenMetaverse.StructuredData.OSDMap;
45
46namespace OpenSim.Services.LLLoginService
47{
48 public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse
49 {
50 protected string m_key;
51 protected string m_value;
52 protected string m_login;
53
54 public static LLFailedLoginResponse UserProblem;
55 public static LLFailedLoginResponse AuthorizationProblem;
56 public static LLFailedLoginResponse GridProblem;
57 public static LLFailedLoginResponse InventoryProblem;
58 public static LLFailedLoginResponse DeadRegionProblem;
59 public static LLFailedLoginResponse LoginBlockedProblem;
60 public static LLFailedLoginResponse UnverifiedAccountProblem;
61 public static LLFailedLoginResponse AlreadyLoggedInProblem;
62 public static LLFailedLoginResponse InternalError;
63
64 static LLFailedLoginResponse()
65 {
66 UserProblem = new LLFailedLoginResponse("key",
67 "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
68 "false");
69 AuthorizationProblem = new LLFailedLoginResponse("key",
70 "Error connecting to grid. Unable to authorize your session into the region.",
71 "false");
72 GridProblem = new LLFailedLoginResponse("key",
73 "Error connecting to the desired location. Try connecting to another region.",
74 "false");
75 InventoryProblem = new LLFailedLoginResponse("key",
76 "The inventory service is not responding. Please notify your login region operator.",
77 "false");
78 DeadRegionProblem = new LLFailedLoginResponse("key",
79 "The region you are attempting to log into is not responding. Please select another region and try again.",
80 "false");
81 LoginBlockedProblem = new LLFailedLoginResponse("presence",
82 "Logins are currently restricted. Please try again later.",
83 "false");
84 UnverifiedAccountProblem = new LLFailedLoginResponse("presence",
85 "Your account has not yet been verified. Please check " +
86 "your email and click the provided link.",
87 "false");
88 AlreadyLoggedInProblem = new LLFailedLoginResponse("presence",
89 "You appear to be already logged in. " +
90 "If this is not the case please wait for your session to timeout. " +
91 "If this takes longer than a few minutes please contact the grid owner. " +
92 "Please wait 5 minutes if you are going to connect to a region nearby to the region you were at previously.",
93 "false");
94 InternalError = new LLFailedLoginResponse("Internal Error", "Error generating Login Response", "false");
95 }
96
97 public LLFailedLoginResponse(string key, string value, string login)
98 {
99 m_key = key;
100 m_value = value;
101 m_login = login;
102 }
103
104 public override Hashtable ToHashtable()
105 {
106 Hashtable loginError = new Hashtable();
107 loginError["reason"] = m_key;
108 loginError["message"] = m_value;
109 loginError["login"] = m_login;
110 return loginError;
111 }
112
113 public override OSD ToOSDMap()
114 {
115 OSDMap map = new OSDMap();
116
117 map["reason"] = OSD.FromString(m_key);
118 map["message"] = OSD.FromString(m_value);
119 map["login"] = OSD.FromString(m_login);
120
121 return map;
122 }
123 }
124
125 /// <summary>
126 /// A class to handle LL login response.
127 /// </summary>
128 public class LLLoginResponse : OpenSim.Services.Interfaces.LoginResponse
129 {
130 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
131 private static Hashtable globalTexturesHash;
132 // Global Textures
133 private static string sunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271";
134 private static string cloudTexture = "dc4b9f0b-d008-45c6-96a4-01dd947ac621";
135 private static string moonTexture = "ec4b9f0b-d008-45c6-96a4-01dd947ac621";
136
137 private Hashtable loginFlagsHash;
138 private Hashtable uiConfigHash;
139
140 private ArrayList loginFlags;
141 private ArrayList globalTextures;
142 private ArrayList eventCategories;
143 private ArrayList uiConfig;
144 private ArrayList classifiedCategories;
145 private ArrayList inventoryRoot;
146 private ArrayList initialOutfit;
147 private ArrayList agentInventory;
148 private ArrayList inventoryLibraryOwner;
149 private ArrayList inventoryLibRoot;
150 private ArrayList inventoryLibrary;
151 private ArrayList activeGestures;
152
153 private UserInfo userProfile;
154
155 private UUID agentID;
156 private UUID sessionID;
157 private UUID secureSessionID;
158
159 // Login Flags
160 private string dst;
161 private string stipendSinceLogin;
162 private string gendered;
163 private string everLoggedIn;
164 private string login;
165 private uint simPort;
166 private uint simHttpPort;
167 private string simAddress;
168 private string agentAccess;
169 private string agentAccessMax;
170 private Int32 circuitCode;
171 private uint regionX;
172 private uint regionY;
173
174 // Login
175 private string firstname;
176 private string lastname;
177
178 // Error Flags
179 private string errorReason;
180 private string errorMessage;
181
182 private string welcomeMessage;
183 private string startLocation;
184 private string allowFirstLife;
185 private string home;
186 private string seedCapability;
187 private string lookAt;
188
189 private BuddyList m_buddyList = null;
190
191 static LLLoginResponse()
192 {
193 // This is being set, but it's not used
194 // not sure why.
195 globalTexturesHash = new Hashtable();
196 globalTexturesHash["sun_texture_id"] = sunTexture;
197 globalTexturesHash["cloud_texture_id"] = cloudTexture;
198 globalTexturesHash["moon_texture_id"] = moonTexture;
199 }
200
201 public LLLoginResponse()
202 {
203 loginFlags = new ArrayList();
204 globalTextures = new ArrayList();
205 eventCategories = new ArrayList();
206 uiConfig = new ArrayList();
207 classifiedCategories = new ArrayList();
208
209 uiConfigHash = new Hashtable();
210
211 // defaultXmlRpcResponse = new XmlRpcResponse();
212 userProfile = new UserInfo();
213 inventoryRoot = new ArrayList();
214 initialOutfit = new ArrayList();
215 agentInventory = new ArrayList();
216 inventoryLibrary = new ArrayList();
217 inventoryLibraryOwner = new ArrayList();
218 activeGestures = new ArrayList();
219
220 SetDefaultValues();
221 }
222
223 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo,
224 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
225 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message,
226 GridRegion home, IPEndPoint clientIP)
227 : this()
228 {
229 FillOutInventoryData(invSkel, libService);
230
231 FillOutActiveGestures(gestures);
232
233 CircuitCode = (int)aCircuit.circuitcode;
234 Lastname = account.LastName;
235 Firstname = account.FirstName;
236 AgentID = account.PrincipalID;
237 SessionID = aCircuit.SessionID;
238 SecureSessionID = aCircuit.SecureSessionID;
239 Message = message;
240 BuddList = ConvertFriendListItem(friendsList);
241 StartLocation = where;
242
243 FillOutHomeData(pinfo, home);
244 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
245
246 FillOutRegionData(destination);
247
248 FillOutSeedCap(aCircuit, destination, clientIP);
249
250 }
251
252 private void FillOutInventoryData(List<InventoryFolderBase> invSkel, ILibraryService libService)
253 {
254 InventoryData inventData = null;
255
256 try
257 {
258 inventData = GetInventorySkeleton(invSkel);
259 }
260 catch (Exception e)
261 {
262 m_log.WarnFormat(
263 "[LLLOGIN SERVICE]: Error processing inventory skeleton of agent {0} - {1}",
264 agentID, e);
265
266 // ignore and continue
267 }
268
269 if (inventData != null)
270 {
271 ArrayList AgentInventoryArray = inventData.InventoryArray;
272
273 Hashtable InventoryRootHash = new Hashtable();
274 InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
275 InventoryRoot = new ArrayList();
276 InventoryRoot.Add(InventoryRootHash);
277 InventorySkeleton = AgentInventoryArray;
278 }
279
280 // Inventory Library Section
281 if (libService != null && libService.LibraryRootFolder != null)
282 {
283 Hashtable InventoryLibRootHash = new Hashtable();
284 InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
285 InventoryLibRoot = new ArrayList();
286 InventoryLibRoot.Add(InventoryLibRootHash);
287
288 InventoryLibraryOwner = GetLibraryOwner(libService.LibraryRootFolder);
289 InventoryLibrary = GetInventoryLibrary(libService);
290 }
291 }
292
293 private void FillOutActiveGestures(List<InventoryItemBase> gestures)
294 {
295 ArrayList list = new ArrayList();
296 if (gestures != null)
297 {
298 foreach (InventoryItemBase gesture in gestures)
299 {
300 Hashtable item = new Hashtable();
301 item["item_id"] = gesture.ID.ToString();
302 item["asset_id"] = gesture.AssetID.ToString();
303 list.Add(item);
304 }
305 }
306 ActiveGestures = list;
307 }
308
309 private void FillOutHomeData(GridUserInfo pinfo, GridRegion home)
310 {
311 int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize;
312 if (home != null)
313 {
314 x = home.RegionLocX;
315 y = home.RegionLocY;
316 }
317
318 Home = string.Format(
319 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
320 x,
321 y,
322 pinfo.HomePosition.X, pinfo.HomePosition.Y, pinfo.HomePosition.Z,
323 pinfo.HomeLookAt.X, pinfo.HomeLookAt.Y, pinfo.HomeLookAt.Z);
324
325 }
326
327 private void FillOutRegionData(GridRegion destination)
328 {
329 IPEndPoint endPoint = destination.ExternalEndPoint;
330 SimAddress = endPoint.Address.ToString();
331 SimPort = (uint)endPoint.Port;
332 RegionX = (uint)destination.RegionLocX;
333 RegionY = (uint)destination.RegionLocY;
334 }
335
336 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient)
337 {
338 string capsSeedPath = String.Empty;
339
340 // Don't use the following! It Fails for logging into any region not on the same port as the http server!
341 // Kept here so it doesn't happen again!
342 // response.SeedCapability = regionInfo.ServerURI + capsSeedPath;
343
344 #region IP Translation for NAT
345 if (ipepClient != null)
346 {
347 capsSeedPath
348 = "http://"
349 + NetworkUtil.GetHostFor(ipepClient.Address, destination.ExternalHostName)
350 + ":"
351 + destination.HttpPort
352 + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
353 }
354 else
355 {
356 capsSeedPath
357 = "http://"
358 + destination.ExternalHostName
359 + ":"
360 + destination.HttpPort
361 + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
362 }
363 #endregion
364
365 SeedCapability = capsSeedPath;
366 }
367
368 private void SetDefaultValues()
369 {
370 DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
371 StipendSinceLogin = "N";
372 Gendered = "Y";
373 EverLoggedIn = "Y";
374 login = "false";
375 firstname = "Test";
376 lastname = "User";
377 agentAccess = "M";
378 agentAccessMax = "A";
379 startLocation = "last";
380 allowFirstLife = "Y";
381
382 ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock.";
383 ErrorReason = "key";
384 welcomeMessage = "Welcome to OpenSim!";
385 seedCapability = String.Empty;
386 home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" +
387 userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" +
388 userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" +
389 userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}";
390 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
391 RegionX = (uint) 255232;
392 RegionY = (uint) 254976;
393
394 // Classifieds;
395 AddClassifiedCategory((Int32) 1, "Shopping");
396 AddClassifiedCategory((Int32) 2, "Land Rental");
397 AddClassifiedCategory((Int32) 3, "Property Rental");
398 AddClassifiedCategory((Int32) 4, "Special Attraction");
399 AddClassifiedCategory((Int32) 5, "New Products");
400 AddClassifiedCategory((Int32) 6, "Employment");
401 AddClassifiedCategory((Int32) 7, "Wanted");
402 AddClassifiedCategory((Int32) 8, "Service");
403 AddClassifiedCategory((Int32) 9, "Personal");
404
405 SessionID = UUID.Random();
406 SecureSessionID = UUID.Random();
407 AgentID = UUID.Random();
408
409 Hashtable InitialOutfitHash = new Hashtable();
410 InitialOutfitHash["folder_name"] = "Nightclub Female";
411 InitialOutfitHash["gender"] = "female";
412 initialOutfit.Add(InitialOutfitHash);
413 }
414
415
416 public override Hashtable ToHashtable()
417 {
418 try
419 {
420 Hashtable responseData = new Hashtable();
421
422 loginFlagsHash = new Hashtable();
423 loginFlagsHash["daylight_savings"] = DST;
424 loginFlagsHash["stipend_since_login"] = StipendSinceLogin;
425 loginFlagsHash["gendered"] = Gendered;
426 loginFlagsHash["ever_logged_in"] = EverLoggedIn;
427 loginFlags.Add(loginFlagsHash);
428
429 responseData["first_name"] = Firstname;
430 responseData["last_name"] = Lastname;
431 responseData["agent_access"] = agentAccess;
432 responseData["agent_access_max"] = agentAccessMax;
433
434 globalTextures.Add(globalTexturesHash);
435 // this.eventCategories.Add(this.eventCategoriesHash);
436
437 AddToUIConfig("allow_first_life", allowFirstLife);
438 uiConfig.Add(uiConfigHash);
439
440 responseData["sim_port"] = (Int32) SimPort;
441 responseData["sim_ip"] = SimAddress;
442 responseData["http_port"] = (Int32)SimHttpPort;
443
444 responseData["agent_id"] = AgentID.ToString();
445 responseData["session_id"] = SessionID.ToString();
446 responseData["secure_session_id"] = SecureSessionID.ToString();
447 responseData["circuit_code"] = CircuitCode;
448 responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
449 responseData["login-flags"] = loginFlags;
450 responseData["global-textures"] = globalTextures;
451 responseData["seed_capability"] = seedCapability;
452
453 responseData["event_categories"] = eventCategories;
454 responseData["event_notifications"] = new ArrayList(); // todo
455 responseData["classified_categories"] = classifiedCategories;
456 responseData["ui-config"] = uiConfig;
457
458 if (agentInventory != null)
459 {
460 responseData["inventory-skeleton"] = agentInventory;
461 responseData["inventory-root"] = inventoryRoot;
462 }
463 responseData["inventory-skel-lib"] = inventoryLibrary;
464 responseData["inventory-lib-root"] = inventoryLibRoot;
465 responseData["gestures"] = activeGestures;
466 responseData["inventory-lib-owner"] = inventoryLibraryOwner;
467 responseData["initial-outfit"] = initialOutfit;
468 responseData["start_location"] = startLocation;
469 responseData["seed_capability"] = seedCapability;
470 responseData["home"] = home;
471 responseData["look_at"] = lookAt;
472 responseData["message"] = welcomeMessage;
473 responseData["region_x"] = (Int32)(RegionX);
474 responseData["region_y"] = (Int32)(RegionY);
475
476 if (m_buddyList != null)
477 {
478 responseData["buddy-list"] = m_buddyList.ToArray();
479 }
480
481 responseData["login"] = "true";
482
483 return responseData;
484 }
485 catch (Exception e)
486 {
487 m_log.Warn("[CLIENT]: LoginResponse: Error creating Hashtable Response: " + e.Message);
488
489 return LLFailedLoginResponse.InternalError.ToHashtable();
490 }
491 }
492
493 public override OSD ToOSDMap()
494 {
495 try
496 {
497 OSDMap map = new OSDMap();
498
499 map["first_name"] = OSD.FromString(Firstname);
500 map["last_name"] = OSD.FromString(Lastname);
501 map["agent_access"] = OSD.FromString(agentAccess);
502 map["agent_access_max"] = OSD.FromString(agentAccessMax);
503
504 map["sim_port"] = OSD.FromInteger(SimPort);
505 map["sim_ip"] = OSD.FromString(SimAddress);
506
507 map["agent_id"] = OSD.FromUUID(AgentID);
508 map["session_id"] = OSD.FromUUID(SessionID);
509 map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
510 map["circuit_code"] = OSD.FromInteger(CircuitCode);
511 map["seconds_since_epoch"] = OSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
512
513 #region Login Flags
514
515 OSDMap loginFlagsLLSD = new OSDMap();
516 loginFlagsLLSD["daylight_savings"] = OSD.FromString(DST);
517 loginFlagsLLSD["stipend_since_login"] = OSD.FromString(StipendSinceLogin);
518 loginFlagsLLSD["gendered"] = OSD.FromString(Gendered);
519 loginFlagsLLSD["ever_logged_in"] = OSD.FromString(EverLoggedIn);
520 map["login-flags"] = WrapOSDMap(loginFlagsLLSD);
521
522 #endregion Login Flags
523
524 #region Global Textures
525
526 OSDMap globalTexturesLLSD = new OSDMap();
527 globalTexturesLLSD["sun_texture_id"] = OSD.FromString(SunTexture);
528 globalTexturesLLSD["cloud_texture_id"] = OSD.FromString(CloudTexture);
529 globalTexturesLLSD["moon_texture_id"] = OSD.FromString(MoonTexture);
530
531 map["global-textures"] = WrapOSDMap(globalTexturesLLSD);
532
533 #endregion Global Textures
534
535 map["seed_capability"] = OSD.FromString(seedCapability);
536
537 map["event_categories"] = ArrayListToOSDArray(eventCategories);
538 //map["event_notifications"] = new OSDArray(); // todo
539 map["classified_categories"] = ArrayListToOSDArray(classifiedCategories);
540
541 #region UI Config
542
543 OSDMap uiConfigLLSD = new OSDMap();
544 uiConfigLLSD["allow_first_life"] = OSD.FromString(allowFirstLife);
545 map["ui-config"] = WrapOSDMap(uiConfigLLSD);
546
547 #endregion UI Config
548
549 #region Inventory
550
551 map["inventory-skeleton"] = ArrayListToOSDArray(agentInventory);
552
553 map["inventory-skel-lib"] = ArrayListToOSDArray(inventoryLibrary);
554 map["inventory-root"] = ArrayListToOSDArray(inventoryRoot); ;
555 map["inventory-lib-root"] = ArrayListToOSDArray(inventoryLibRoot);
556 map["inventory-lib-owner"] = ArrayListToOSDArray(inventoryLibraryOwner);
557
558 #endregion Inventory
559
560 map["gestures"] = ArrayListToOSDArray(activeGestures);
561
562 map["initial-outfit"] = ArrayListToOSDArray(initialOutfit);
563 map["start_location"] = OSD.FromString(startLocation);
564
565 map["seed_capability"] = OSD.FromString(seedCapability);
566 map["home"] = OSD.FromString(home);
567 map["look_at"] = OSD.FromString(lookAt);
568 map["message"] = OSD.FromString(welcomeMessage);
569 map["region_x"] = OSD.FromInteger(RegionX);
570 map["region_y"] = OSD.FromInteger(RegionY);
571
572 if (m_buddyList != null)
573 {
574 map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray());
575 }
576
577 map["login"] = OSD.FromString("true");
578
579 return map;
580 }
581 catch (Exception e)
582 {
583 m_log.Warn("[CLIENT]: LoginResponse: Error creating LLSD Response: " + e.Message);
584
585 return LLFailedLoginResponse.InternalError.ToOSDMap();
586 }
587 }
588
589 public OSDArray ArrayListToOSDArray(ArrayList arrlst)
590 {
591 OSDArray llsdBack = new OSDArray();
592 foreach (Hashtable ht in arrlst)
593 {
594 OSDMap mp = new OSDMap();
595 foreach (DictionaryEntry deHt in ht)
596 {
597 mp.Add((string)deHt.Key, OSDString.FromObject(deHt.Value));
598 }
599 llsdBack.Add(mp);
600 }
601 return llsdBack;
602 }
603
604 private static OSDArray WrapOSDMap(OSDMap wrapMe)
605 {
606 OSDArray array = new OSDArray();
607 array.Add(wrapMe);
608 return array;
609 }
610
611 public void SetEventCategories(string category, string value)
612 {
613 // this.eventCategoriesHash[category] = value;
614 //TODO
615 }
616
617 public void AddToUIConfig(string itemName, string item)
618 {
619 uiConfigHash[itemName] = item;
620 }
621
622 public void AddClassifiedCategory(Int32 ID, string categoryName)
623 {
624 Hashtable hash = new Hashtable();
625 hash["category_name"] = categoryName;
626 hash["category_id"] = ID;
627 classifiedCategories.Add(hash);
628 // this.classifiedCategoriesHash.Clear();
629 }
630
631
632 private static LLLoginResponse.BuddyList ConvertFriendListItem(FriendInfo[] friendsList)
633 {
634 LLLoginResponse.BuddyList buddylistreturn = new LLLoginResponse.BuddyList();
635 foreach (FriendInfo finfo in friendsList)
636 {
637 if (finfo.TheirFlags == -1)
638 continue;
639 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
640 buddyitem.BuddyID = finfo.Friend;
641 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
642 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
643 buddylistreturn.AddNewBuddy(buddyitem);
644 }
645 return buddylistreturn;
646 }
647
648 private InventoryData GetInventorySkeleton(List<InventoryFolderBase> folders)
649 {
650 UUID rootID = UUID.Zero;
651 ArrayList AgentInventoryArray = new ArrayList();
652 Hashtable TempHash;
653 foreach (InventoryFolderBase InvFolder in folders)
654 {
655 if (InvFolder.ParentID == UUID.Zero)
656 {
657 rootID = InvFolder.ID;
658 }
659 TempHash = new Hashtable();
660 TempHash["name"] = InvFolder.Name;
661 TempHash["parent_id"] = InvFolder.ParentID.ToString();
662 TempHash["version"] = (Int32)InvFolder.Version;
663 TempHash["type_default"] = (Int32)InvFolder.Type;
664 TempHash["folder_id"] = InvFolder.ID.ToString();
665 AgentInventoryArray.Add(TempHash);
666 }
667
668 return new InventoryData(AgentInventoryArray, rootID);
669
670 }
671
672 /// <summary>
673 /// Converts the inventory library skeleton into the form required by the rpc request.
674 /// </summary>
675 /// <returns></returns>
676 protected virtual ArrayList GetInventoryLibrary(ILibraryService library)
677 {
678 Dictionary<UUID, InventoryFolderImpl> rootFolders = library.GetAllFolders();
679 m_log.DebugFormat("[LLOGIN]: Library has {0} folders", rootFolders.Count);
680 //Dictionary<UUID, InventoryFolderImpl> rootFolders = new Dictionary<UUID,InventoryFolderImpl>();
681 ArrayList folderHashes = new ArrayList();
682
683 foreach (InventoryFolderBase folder in rootFolders.Values)
684 {
685 Hashtable TempHash = new Hashtable();
686 TempHash["name"] = folder.Name;
687 TempHash["parent_id"] = folder.ParentID.ToString();
688 TempHash["version"] = (Int32)folder.Version;
689 TempHash["type_default"] = (Int32)folder.Type;
690 TempHash["folder_id"] = folder.ID.ToString();
691 folderHashes.Add(TempHash);
692 }
693
694 return folderHashes;
695 }
696
697 /// <summary>
698 ///
699 /// </summary>
700 /// <returns></returns>
701 protected virtual ArrayList GetLibraryOwner(InventoryFolderImpl libFolder)
702 {
703 //for now create random inventory library owner
704 Hashtable TempHash = new Hashtable();
705 TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000"; // libFolder.Owner
706 ArrayList inventoryLibOwner = new ArrayList();
707 inventoryLibOwner.Add(TempHash);
708 return inventoryLibOwner;
709 }
710
711 public class InventoryData
712 {
713 public ArrayList InventoryArray = null;
714 public UUID RootFolderID = UUID.Zero;
715
716 public InventoryData(ArrayList invList, UUID rootID)
717 {
718 InventoryArray = invList;
719 RootFolderID = rootID;
720 }
721 }
722
723 #region Properties
724
725 public string Login
726 {
727 get { return login; }
728 set { login = value; }
729 }
730
731 public string DST
732 {
733 get { return dst; }
734 set { dst = value; }
735 }
736
737 public string StipendSinceLogin
738 {
739 get { return stipendSinceLogin; }
740 set { stipendSinceLogin = value; }
741 }
742
743 public string Gendered
744 {
745 get { return gendered; }
746 set { gendered = value; }
747 }
748
749 public string EverLoggedIn
750 {
751 get { return everLoggedIn; }
752 set { everLoggedIn = value; }
753 }
754
755 public uint SimPort
756 {
757 get { return simPort; }
758 set { simPort = value; }
759 }
760
761 public uint SimHttpPort
762 {
763 get { return simHttpPort; }
764 set { simHttpPort = value; }
765 }
766
767 public string SimAddress
768 {
769 get { return simAddress; }
770 set { simAddress = value; }
771 }
772
773 public UUID AgentID
774 {
775 get { return agentID; }
776 set { agentID = value; }
777 }
778
779 public UUID SessionID
780 {
781 get { return sessionID; }
782 set { sessionID = value; }
783 }
784
785 public UUID SecureSessionID
786 {
787 get { return secureSessionID; }
788 set { secureSessionID = value; }
789 }
790
791 public Int32 CircuitCode
792 {
793 get { return circuitCode; }
794 set { circuitCode = value; }
795 }
796
797 public uint RegionX
798 {
799 get { return regionX; }
800 set { regionX = value; }
801 }
802
803 public uint RegionY
804 {
805 get { return regionY; }
806 set { regionY = value; }
807 }
808
809 public string SunTexture
810 {
811 get { return sunTexture; }
812 set { sunTexture = value; }
813 }
814
815 public string CloudTexture
816 {
817 get { return cloudTexture; }
818 set { cloudTexture = value; }
819 }
820
821 public string MoonTexture
822 {
823 get { return moonTexture; }
824 set { moonTexture = value; }
825 }
826
827 public string Firstname
828 {
829 get { return firstname; }
830 set { firstname = value; }
831 }
832
833 public string Lastname
834 {
835 get { return lastname; }
836 set { lastname = value; }
837 }
838
839 public string AgentAccess
840 {
841 get { return agentAccess; }
842 set { agentAccess = value; }
843 }
844
845 public string AgentAccessMax
846 {
847 get { return agentAccessMax; }
848 set { agentAccessMax = value; }
849 }
850
851 public string StartLocation
852 {
853 get { return startLocation; }
854 set { startLocation = value; }
855 }
856
857 public string LookAt
858 {
859 get { return lookAt; }
860 set { lookAt = value; }
861 }
862
863 public string SeedCapability
864 {
865 get { return seedCapability; }
866 set { seedCapability = value; }
867 }
868
869 public string ErrorReason
870 {
871 get { return errorReason; }
872 set { errorReason = value; }
873 }
874
875 public string ErrorMessage
876 {
877 get { return errorMessage; }
878 set { errorMessage = value; }
879 }
880
881 public ArrayList InventoryRoot
882 {
883 get { return inventoryRoot; }
884 set { inventoryRoot = value; }
885 }
886
887 public ArrayList InventorySkeleton
888 {
889 get { return agentInventory; }
890 set { agentInventory = value; }
891 }
892
893 public ArrayList InventoryLibrary
894 {
895 get { return inventoryLibrary; }
896 set { inventoryLibrary = value; }
897 }
898
899 public ArrayList InventoryLibraryOwner
900 {
901 get { return inventoryLibraryOwner; }
902 set { inventoryLibraryOwner = value; }
903 }
904
905 public ArrayList InventoryLibRoot
906 {
907 get { return inventoryLibRoot; }
908 set { inventoryLibRoot = value; }
909 }
910
911 public ArrayList ActiveGestures
912 {
913 get { return activeGestures; }
914 set { activeGestures = value; }
915 }
916
917 public string Home
918 {
919 get { return home; }
920 set { home = value; }
921 }
922
923 public string Message
924 {
925 get { return welcomeMessage; }
926 set { welcomeMessage = value; }
927 }
928
929 public BuddyList BuddList
930 {
931 get { return m_buddyList; }
932 set { m_buddyList = value; }
933 }
934
935 #endregion
936
937 public class UserInfo
938 {
939 public string firstname;
940 public string lastname;
941 public ulong homeregionhandle;
942 public Vector3 homepos;
943 public Vector3 homelookat;
944 }
945
946 public class BuddyList
947 {
948 public List<BuddyInfo> Buddies = new List<BuddyInfo>();
949
950 public void AddNewBuddy(BuddyInfo buddy)
951 {
952 if (!Buddies.Contains(buddy))
953 {
954 Buddies.Add(buddy);
955 }
956 }
957
958 public ArrayList ToArray()
959 {
960 ArrayList buddyArray = new ArrayList();
961 foreach (BuddyInfo buddy in Buddies)
962 {
963 buddyArray.Add(buddy.ToHashTable());
964 }
965 return buddyArray;
966 }
967
968 public class BuddyInfo
969 {
970 public int BuddyRightsHave = 1;
971 public int BuddyRightsGiven = 1;
972 public string BuddyID;
973
974 public BuddyInfo(string buddyID)
975 {
976 BuddyID = buddyID;
977 }
978
979 public BuddyInfo(UUID buddyID)
980 {
981 BuddyID = buddyID.ToString();
982 }
983
984 public Hashtable ToHashTable()
985 {
986 Hashtable hTable = new Hashtable();
987 hTable["buddy_rights_has"] = BuddyRightsHave;
988 hTable["buddy_rights_given"] = BuddyRightsGiven;
989 hTable["buddy_id"] = BuddyID;
990 return hTable;
991 }
992 }
993 }
994 }
995}
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
new file mode 100644
index 0000000..83f9ade
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -0,0 +1,813 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using System.Text.RegularExpressions;
34
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Capabilities;
41using OpenSim.Framework.Console;
42using OpenSim.Server.Base;
43using OpenSim.Services.Interfaces;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
46using OpenSim.Services.Connectors.Hypergrid;
47
48namespace OpenSim.Services.LLLoginService
49{
50 public class LLLoginService : ILoginService
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 private static bool Initialized = false;
54
55 protected IUserAccountService m_UserAccountService;
56 protected IGridUserService m_GridUserService;
57 protected IAuthenticationService m_AuthenticationService;
58 protected IInventoryService m_InventoryService;
59 protected IGridService m_GridService;
60 protected IPresenceService m_PresenceService;
61 protected ISimulationService m_LocalSimulationService;
62 protected ISimulationService m_RemoteSimulationService;
63 protected ILibraryService m_LibraryService;
64 protected IFriendsService m_FriendsService;
65 protected IAvatarService m_AvatarService;
66 protected IUserAgentService m_UserAgentService;
67
68 protected GatekeeperServiceConnector m_GatekeeperConnector;
69
70 protected string m_DefaultRegionName;
71 protected string m_WelcomeMessage;
72 protected bool m_RequireInventory;
73 protected int m_MinLoginLevel;
74 protected string m_GatekeeperURL;
75 protected bool m_AllowRemoteSetLoginLevel;
76
77 IConfig m_LoginServerConfig;
78
79 public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
80 {
81 m_LoginServerConfig = config.Configs["LoginService"];
82 if (m_LoginServerConfig == null)
83 throw new Exception(String.Format("No section LoginService in config file"));
84
85 string accountService = m_LoginServerConfig.GetString("UserAccountService", String.Empty);
86 string gridUserService = m_LoginServerConfig.GetString("GridUserService", String.Empty);
87 string agentService = m_LoginServerConfig.GetString("UserAgentService", String.Empty);
88 string authService = m_LoginServerConfig.GetString("AuthenticationService", String.Empty);
89 string invService = m_LoginServerConfig.GetString("InventoryService", String.Empty);
90 string gridService = m_LoginServerConfig.GetString("GridService", String.Empty);
91 string presenceService = m_LoginServerConfig.GetString("PresenceService", String.Empty);
92 string libService = m_LoginServerConfig.GetString("LibraryService", String.Empty);
93 string friendsService = m_LoginServerConfig.GetString("FriendsService", String.Empty);
94 string avatarService = m_LoginServerConfig.GetString("AvatarService", String.Empty);
95 string simulationService = m_LoginServerConfig.GetString("SimulationService", String.Empty);
96
97 m_DefaultRegionName = m_LoginServerConfig.GetString("DefaultRegion", String.Empty);
98 m_WelcomeMessage = m_LoginServerConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
99 m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true);
100 m_AllowRemoteSetLoginLevel = m_LoginServerConfig.GetBoolean("AllowRemoteSetLoginLevel", false);
101 m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0);
102 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty);
103
104 // These are required; the others aren't
105 if (accountService == string.Empty || authService == string.Empty)
106 throw new Exception("LoginService is missing service specifications");
107
108 Object[] args = new Object[] { config };
109 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
110 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
111 m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
112 m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
113
114 if (gridService != string.Empty)
115 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
116 if (presenceService != string.Empty)
117 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
118 if (avatarService != string.Empty)
119 m_AvatarService = ServerUtils.LoadPlugin<IAvatarService>(avatarService, args);
120 if (friendsService != string.Empty)
121 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(friendsService, args);
122 if (simulationService != string.Empty)
123 m_RemoteSimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
124 if (agentService != string.Empty)
125 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(agentService, args);
126
127 //
128 // deal with the services given as argument
129 //
130 m_LocalSimulationService = simService;
131 if (libraryService != null)
132 {
133 m_log.DebugFormat("[LLOGIN SERVICE]: Using LibraryService given as argument");
134 m_LibraryService = libraryService;
135 }
136 else if (libService != string.Empty)
137 {
138 m_log.DebugFormat("[LLOGIN SERVICE]: Using instantiated LibraryService");
139 m_LibraryService = ServerUtils.LoadPlugin<ILibraryService>(libService, args);
140 }
141
142 m_GatekeeperConnector = new GatekeeperServiceConnector();
143
144 if (!Initialized)
145 {
146 Initialized = true;
147 RegisterCommands();
148 }
149
150 m_log.DebugFormat("[LLOGIN SERVICE]: Starting...");
151
152 }
153
154 public LLLoginService(IConfigSource config) : this(config, null, null)
155 {
156 }
157
158 public Hashtable SetLevel(string firstName, string lastName, string passwd, int level, IPEndPoint clientIP)
159 {
160 Hashtable response = new Hashtable();
161 response["success"] = "false";
162
163 if (!m_AllowRemoteSetLoginLevel)
164 return response;
165
166 try
167 {
168 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
169 if (account == null)
170 {
171 m_log.InfoFormat("[LLOGIN SERVICE]: Set Level failed, user {0} {1} not found", firstName, lastName);
172 return response;
173 }
174
175 if (account.UserLevel < 200)
176 {
177 m_log.InfoFormat("[LLOGIN SERVICE]: Set Level failed, reason: user level too low");
178 return response;
179 }
180
181 //
182 // Authenticate this user
183 //
184 // We don't support clear passwords here
185 //
186 string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30);
187 UUID secureSession = UUID.Zero;
188 if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
189 {
190 m_log.InfoFormat("[LLOGIN SERVICE]: SetLevel failed, reason: authentication failed");
191 return response;
192 }
193 }
194 catch (Exception e)
195 {
196 m_log.Error("[LLOGIN SERVICE]: SetLevel failed, exception " + e.ToString());
197 return response;
198 }
199
200 m_MinLoginLevel = level;
201 m_log.InfoFormat("[LLOGIN SERVICE]: Login level set to {0} by {1} {2}", level, firstName, lastName);
202
203 response["success"] = true;
204 return response;
205 }
206
207 public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, string clientVersion, IPEndPoint clientIP)
208 {
209 bool success = false;
210 UUID session = UUID.Random();
211
212 try
213 {
214 //
215 // Get the account and check that it exists
216 //
217 UserAccount account = m_UserAccountService.GetUserAccount(scopeID, firstName, lastName);
218 if (account == null)
219 {
220 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
221 return LLFailedLoginResponse.UserProblem;
222 }
223
224 if (account.UserLevel < 0)
225 {
226 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: Unverified account");
227 return LLFailedLoginResponse.UnverifiedAccountProblem;
228 }
229
230 if (account.UserLevel < m_MinLoginLevel)
231 {
232 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}", account.UserLevel);
233 return LLFailedLoginResponse.LoginBlockedProblem;
234 }
235
236 // If a scope id is requested, check that the account is in
237 // that scope, or unscoped.
238 //
239 if (scopeID != UUID.Zero)
240 {
241 if (account.ScopeID != scopeID && account.ScopeID != UUID.Zero)
242 {
243 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
244 return LLFailedLoginResponse.UserProblem;
245 }
246 }
247 else
248 {
249 scopeID = account.ScopeID;
250 }
251
252 //
253 // Authenticate this user
254 //
255 if (!passwd.StartsWith("$1$"))
256 passwd = "$1$" + Util.Md5Hash(passwd);
257 passwd = passwd.Remove(0, 3); //remove $1$
258 string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30);
259 UUID secureSession = UUID.Zero;
260 if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
261 {
262 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: authentication failed");
263 return LLFailedLoginResponse.UserProblem;
264 }
265
266 //
267 // Get the user's inventory
268 //
269 if (m_RequireInventory && m_InventoryService == null)
270 {
271 m_log.WarnFormat("[LLOGIN SERVICE]: Login failed, reason: inventory service not set up");
272 return LLFailedLoginResponse.InventoryProblem;
273 }
274 List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
275 if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0)))
276 {
277 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: unable to retrieve user inventory");
278 return LLFailedLoginResponse.InventoryProblem;
279 }
280
281 // Get active gestures
282 List<InventoryItemBase> gestures = m_InventoryService.GetActiveGestures(account.PrincipalID);
283 m_log.DebugFormat("[LLOGIN SERVICE]: {0} active gestures", gestures.Count);
284
285 //
286 // Login the presence
287 //
288 if (m_PresenceService != null)
289 {
290 success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession);
291 if (!success)
292 {
293 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: could not login presence");
294 return LLFailedLoginResponse.GridProblem;
295 }
296 }
297
298 //
299 // Change Online status and get the home region
300 //
301 GridRegion home = null;
302 GridUserInfo guinfo = m_GridUserService.LoggedIn(account.PrincipalID.ToString());
303 if (guinfo != null && (guinfo.HomeRegionID != UUID.Zero) && m_GridService != null)
304 {
305 home = m_GridService.GetRegionByUUID(scopeID, guinfo.HomeRegionID);
306 }
307 if (guinfo == null)
308 {
309 // something went wrong, make something up, so that we don't have to test this anywhere else
310 guinfo = new GridUserInfo();
311 guinfo.LastPosition = guinfo.HomePosition = new Vector3(128, 128, 30);
312 }
313
314 //
315 // Find the destination region/grid
316 //
317 string where = string.Empty;
318 Vector3 position = Vector3.Zero;
319 Vector3 lookAt = Vector3.Zero;
320 GridRegion gatekeeper = null;
321 GridRegion destination = FindDestination(account, scopeID, guinfo, session, startLocation, home, out gatekeeper, out where, out position, out lookAt);
322 if (destination == null)
323 {
324 m_PresenceService.LogoutAgent(session);
325 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
326 return LLFailedLoginResponse.GridProblem;
327 }
328
329 //
330 // Get the avatar
331 //
332 AvatarData avatar = null;
333 if (m_AvatarService != null)
334 {
335 avatar = m_AvatarService.GetAvatar(account.PrincipalID);
336 }
337
338 //
339 // Instantiate/get the simulation interface and launch an agent at the destination
340 //
341 string reason = string.Empty;
342 AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, clientIP, out where, out reason);
343
344 if (aCircuit == null)
345 {
346 m_PresenceService.LogoutAgent(session);
347 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason);
348 return LLFailedLoginResponse.AuthorizationProblem;
349
350 }
351 // Get Friends list
352 FriendInfo[] friendsList = new FriendInfo[0];
353 if (m_FriendsService != null)
354 {
355 friendsList = m_FriendsService.GetFriends(account.PrincipalID);
356 m_log.DebugFormat("[LLOGIN SERVICE]: Retrieved {0} friends", friendsList.Length);
357 }
358
359 //
360 // Finally, fill out the response and return it
361 //
362 LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
363 where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP);
364
365 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
366 return response;
367 }
368 catch (Exception e)
369 {
370 m_log.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2} {3}", firstName, lastName, e.ToString(), e.StackTrace);
371 if (m_PresenceService != null)
372 m_PresenceService.LogoutAgent(session);
373 return LLFailedLoginResponse.InternalError;
374 }
375 }
376
377 protected GridRegion FindDestination(UserAccount account, UUID scopeID, GridUserInfo pinfo, UUID sessionID, string startLocation, GridRegion home, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt)
378 {
379 m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation);
380
381 gatekeeper = null;
382 where = "home";
383 position = new Vector3(128, 128, 0);
384 lookAt = new Vector3(0, 1, 0);
385
386 if (m_GridService == null)
387 return null;
388
389 if (startLocation.Equals("home"))
390 {
391 // logging into home region
392 if (pinfo == null)
393 return null;
394
395 GridRegion region = null;
396
397 bool tryDefaults = false;
398
399 if (home == null)
400 {
401 m_log.WarnFormat(
402 "[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set",
403 account.FirstName, account.LastName);
404
405 tryDefaults = true;
406 }
407 else
408 {
409 region = home;
410
411 position = pinfo.HomePosition;
412 lookAt = pinfo.HomeLookAt;
413 }
414
415 if (tryDefaults)
416 {
417 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
418 if (defaults != null && defaults.Count > 0)
419 {
420 region = defaults[0];
421 where = "safe";
422 }
423 else
424 {
425 m_log.WarnFormat("[LLOGIN SERVICE]: User {0} {1} does not have a valid home and this grid does not have default locations. Attempting to find random region",
426 account.FirstName, account.LastName);
427 defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
428 if (defaults != null && defaults.Count > 0)
429 {
430 region = defaults[0];
431 where = "safe";
432 }
433 }
434 }
435
436 return region;
437 }
438 else if (startLocation.Equals("last"))
439 {
440 // logging into last visited region
441 where = "last";
442
443 if (pinfo == null)
444 return null;
445
446 GridRegion region = null;
447
448 if (pinfo.LastRegionID.Equals(UUID.Zero) || (region = m_GridService.GetRegionByUUID(scopeID, pinfo.LastRegionID)) == null)
449 {
450 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
451 if (defaults != null && defaults.Count > 0)
452 {
453 region = defaults[0];
454 where = "safe";
455 }
456 else
457 {
458 m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
459 defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
460 if (defaults != null && defaults.Count > 0)
461 {
462 region = defaults[0];
463 where = "safe";
464 }
465 }
466
467 }
468 else
469 {
470 position = pinfo.LastPosition;
471 lookAt = pinfo.LastLookAt;
472 }
473
474 return region;
475 }
476 else
477 {
478 // free uri form
479 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
480 where = "url";
481 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
482 Match uriMatch = reURI.Match(startLocation);
483 if (uriMatch == null)
484 {
485 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, but can't process it", startLocation);
486 return null;
487 }
488 else
489 {
490 position = new Vector3(float.Parse(uriMatch.Groups["x"].Value, Culture.NumberFormatInfo),
491 float.Parse(uriMatch.Groups["y"].Value, Culture.NumberFormatInfo),
492 float.Parse(uriMatch.Groups["z"].Value, Culture.NumberFormatInfo));
493
494 string regionName = uriMatch.Groups["region"].ToString();
495 if (regionName != null)
496 {
497 if (!regionName.Contains("@"))
498 {
499 List<GridRegion> regions = m_GridService.GetRegionsByName(scopeID, regionName, 1);
500 if ((regions == null) || (regions != null && regions.Count == 0))
501 {
502 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}. Trying defaults.", startLocation, regionName);
503 regions = m_GridService.GetDefaultRegions(scopeID);
504 if (regions != null && regions.Count > 0)
505 {
506 where = "safe";
507 return regions[0];
508 }
509 else
510 {
511 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation);
512 return null;
513 }
514 }
515 return regions[0];
516 }
517 else
518 {
519 if (m_UserAgentService == null)
520 {
521 m_log.WarnFormat("[LLLOGIN SERVICE]: This llogin service is not running a user agent service, as such it can't lauch agents at foreign grids");
522 return null;
523 }
524 string[] parts = regionName.Split(new char[] { '@' });
525 if (parts.Length < 2)
526 {
527 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName);
528 return null;
529 }
530 // Valid specification of a remote grid
531
532 regionName = parts[0];
533 string domainLocator = parts[1];
534 parts = domainLocator.Split(new char[] {':'});
535 string domainName = parts[0];
536 uint port = 0;
537 if (parts.Length > 1)
538 UInt32.TryParse(parts[1], out port);
539
540 GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
541 return region;
542 }
543 }
544 else
545 {
546 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
547 if (defaults != null && defaults.Count > 0)
548 {
549 where = "safe";
550 return defaults[0];
551 }
552 else
553 return null;
554 }
555 }
556 //response.LookAt = "[r0,r1,r0]";
557 //// can be: last, home, safe, url
558 //response.StartLocation = "url";
559
560 }
561
562 }
563
564 private GridRegion FindForeignRegion(string domainName, uint port, string regionName, out GridRegion gatekeeper)
565 {
566 gatekeeper = new GridRegion();
567 gatekeeper.ExternalHostName = domainName;
568 gatekeeper.HttpPort = port;
569 gatekeeper.RegionName = regionName;
570 gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
571
572 UUID regionID;
573 ulong handle;
574 string imageURL = string.Empty, reason = string.Empty;
575 if (m_GatekeeperConnector.LinkRegion(gatekeeper, out regionID, out handle, out domainName, out imageURL, out reason))
576 {
577 GridRegion destination = m_GatekeeperConnector.GetHyperlinkRegion(gatekeeper, regionID);
578 return destination;
579 }
580
581 return null;
582 }
583
584 private string hostName = string.Empty;
585 private int port = 0;
586
587 private void SetHostAndPort(string url)
588 {
589 try
590 {
591 Uri uri = new Uri(url);
592 hostName = uri.Host;
593 port = uri.Port;
594 }
595 catch
596 {
597 m_log.WarnFormat("[LLLogin SERVICE]: Unable to parse GatekeeperURL {0}", url);
598 }
599 }
600
601 protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar,
602 UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, IPEndPoint clientIP, out string where, out string reason)
603 {
604 where = currentWhere;
605 ISimulationService simConnector = null;
606 reason = string.Empty;
607 uint circuitCode = 0;
608 AgentCircuitData aCircuit = null;
609
610 if (m_UserAgentService == null)
611 {
612 // HG standalones have both a localSimulatonDll and a remoteSimulationDll
613 // non-HG standalones have just a localSimulationDll
614 // independent login servers have just a remoteSimulationDll
615 if (m_LocalSimulationService != null)
616 simConnector = m_LocalSimulationService;
617 else if (m_RemoteSimulationService != null)
618 simConnector = m_RemoteSimulationService;
619 }
620 else // User Agent Service is on
621 {
622 if (gatekeeper == null) // login to local grid
623 {
624 if (hostName == string.Empty)
625 SetHostAndPort(m_GatekeeperURL);
626
627 gatekeeper = new GridRegion(destination);
628 gatekeeper.ExternalHostName = hostName;
629 gatekeeper.HttpPort = (uint)port;
630
631 }
632 else // login to foreign grid
633 {
634 }
635 }
636
637 bool success = false;
638
639 if (m_UserAgentService == null && simConnector != null)
640 {
641 circuitCode = (uint)Util.RandomClass.Next(); ;
642 aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer);
643 success = LaunchAgentDirectly(simConnector, destination, aCircuit, out reason);
644 if (!success && m_GridService != null)
645 {
646 // Try the fallback regions
647 List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
648 if (fallbacks != null)
649 {
650 foreach (GridRegion r in fallbacks)
651 {
652 success = LaunchAgentDirectly(simConnector, r, aCircuit, out reason);
653 if (success)
654 {
655 where = "safe";
656 destination = r;
657 break;
658 }
659 }
660 }
661 }
662 }
663
664 if (m_UserAgentService != null)
665 {
666 circuitCode = (uint)Util.RandomClass.Next(); ;
667 aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer);
668 success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, clientIP, out reason);
669 if (!success && m_GridService != null)
670 {
671 // Try the fallback regions
672 List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
673 if (fallbacks != null)
674 {
675 foreach (GridRegion r in fallbacks)
676 {
677 success = LaunchAgentIndirectly(gatekeeper, r, aCircuit, clientIP, out reason);
678 if (success)
679 {
680 where = "safe";
681 destination = r;
682 break;
683 }
684 }
685 }
686 }
687 }
688
689 if (success)
690 return aCircuit;
691 else
692 return null;
693 }
694
695 private AgentCircuitData MakeAgent(GridRegion region, UserAccount account,
696 AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position, string viewer)
697 {
698 AgentCircuitData aCircuit = new AgentCircuitData();
699
700 aCircuit.AgentID = account.PrincipalID;
701 if (avatar != null)
702 aCircuit.Appearance = avatar.ToAvatarAppearance(account.PrincipalID);
703 else
704 aCircuit.Appearance = new AvatarAppearance(account.PrincipalID);
705
706 //aCircuit.BaseFolder = irrelevant
707 aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
708 aCircuit.child = false; // the first login agent is root
709 aCircuit.ChildrenCapSeeds = new Dictionary<ulong, string>();
710 aCircuit.circuitcode = circuit;
711 aCircuit.firstname = account.FirstName;
712 //aCircuit.InventoryFolder = irrelevant
713 aCircuit.lastname = account.LastName;
714 aCircuit.SecureSessionID = secureSession;
715 aCircuit.SessionID = session;
716 aCircuit.startpos = position;
717 aCircuit.Viewer = viewer;
718 SetServiceURLs(aCircuit, account);
719
720 return aCircuit;
721
722 //m_UserAgentService.LoginAgentToGrid(aCircuit, GatekeeperServiceConnector, region, out reason);
723 //if (simConnector.CreateAgent(region, aCircuit, 0, out reason))
724 // return aCircuit;
725
726 //return null;
727
728 }
729
730 private void SetServiceURLs(AgentCircuitData aCircuit, UserAccount account)
731 {
732 aCircuit.ServiceURLs = new Dictionary<string, object>();
733 if (account.ServiceURLs == null)
734 return;
735
736 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs)
737 {
738 if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty))
739 {
740 aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty);
741 }
742 else
743 {
744 aCircuit.ServiceURLs[kvp.Key] = kvp.Value;
745 }
746 }
747 }
748
749 private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, out string reason)
750 {
751 return simConnector.CreateAgent(region, aCircuit, (int)Constants.TeleportFlags.ViaLogin, out reason);
752 }
753
754 private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason)
755 {
756 m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
757 if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason))
758 {
759 // We may need to do this at some point,
760 // so leaving it here in comments.
761 //IPAddress addr = NetworkUtil.GetIPFor(clientIP.Address, destination.ExternalEndPoint.Address);
762 m_UserAgentService.SetClientToken(aCircuit.SessionID, /*addr.Address.ToString() */ clientIP.Address.ToString());
763 return true;
764 }
765 return false;
766 }
767
768 #region Console Commands
769 private void RegisterCommands()
770 {
771 //MainConsole.Instance.Commands.AddCommand
772 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login level",
773 "login level <level>",
774 "Set the minimum user level to log in", HandleLoginCommand);
775
776 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login reset",
777 "login reset",
778 "Reset the login level to allow all users",
779 HandleLoginCommand);
780
781 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login text",
782 "login text <text>",
783 "Set the text users will see on login", HandleLoginCommand);
784
785 }
786
787 private void HandleLoginCommand(string module, string[] cmd)
788 {
789 string subcommand = cmd[1];
790
791 switch (subcommand)
792 {
793 case "level":
794 // Set the minimum level to allow login
795 // Useful to allow grid update without worrying about users.
796 // or fixing critical issues
797 //
798 if (cmd.Length > 2)
799 Int32.TryParse(cmd[2], out m_MinLoginLevel);
800 break;
801 case "reset":
802 m_MinLoginLevel = 0;
803 break;
804 case "text":
805 if (cmd.Length > 2)
806 m_WelcomeMessage = cmd[2];
807 break;
808 }
809 }
810 }
811
812 #endregion
813}
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs
index 2157462..19f636a 100644
--- a/OpenSim/Services/PresenceService/PresenceService.cs
+++ b/OpenSim/Services/PresenceService/PresenceService.cs
@@ -41,27 +41,107 @@ 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 PresenceData[] d = m_Database.Get("UserID", userID);
56 p.Data = new Dictionary<string, string>();
57 58
58 p.UUID = presence.PrincipalID; 59 PresenceData data = new PresenceData();
59 p.currentRegion = presence.RegionID;
60 60
61 foreach (KeyValuePair<string, string> kvp in presence.Data) 61 data.UserID = userID;
62 p.Data[kvp.Key] = kvp.Value; 62 data.RegionID = UUID.Zero;
63 data.SessionID = sessionID;
64 data.Data = new Dictionary<string, string>();
65 data.Data["SecureSessionID"] = secureSessionID.ToString();
66
67 m_Database.Store(data);
63 68
64 return false; 69 m_log.DebugFormat("[PRESENCE SERVICE]: LoginAgent {0} with session {1} and ssession {2}",
70 userID, sessionID, secureSessionID);
71 return true;
65 } 72 }
73
74 public bool LogoutAgent(UUID sessionID)
75 {
76 m_log.DebugFormat("[PRESENCE SERVICE]: Session {0} logout", sessionID);
77 return m_Database.Delete("SessionID", sessionID.ToString());
78 }
79
80 public bool LogoutRegionAgents(UUID regionID)
81 {
82 m_Database.LogoutRegionAgents(regionID);
83
84 return true;
85 }
86
87
88 public bool ReportAgent(UUID sessionID, UUID regionID)
89 {
90 m_log.DebugFormat("[PRESENCE SERVICE]: ReportAgent with session {0} in region {1}", sessionID, regionID);
91 try
92 {
93 PresenceData pdata = m_Database.Get(sessionID);
94 if (pdata == null)
95 return false;
96 if (pdata.Data == null)
97 return false;
98
99 return m_Database.ReportAgent(sessionID, regionID);
100 }
101 catch (Exception e)
102 {
103 m_log.DebugFormat("[PRESENCE SERVICE]: ReportAgent threw exception {0}", e.StackTrace);
104 return false;
105 }
106 }
107
108 public PresenceInfo GetAgent(UUID sessionID)
109 {
110 PresenceInfo ret = new PresenceInfo();
111
112 PresenceData data = m_Database.Get(sessionID);
113 if (data == null)
114 return null;
115
116 ret.UserID = data.UserID;
117 ret.RegionID = data.RegionID;
118
119 return ret;
120 }
121
122 public PresenceInfo[] GetAgents(string[] userIDs)
123 {
124 List<PresenceInfo> info = new List<PresenceInfo>();
125
126 foreach (string userIDStr in userIDs)
127 {
128 PresenceData[] data = m_Database.Get("UserID",
129 userIDStr);
130
131 foreach (PresenceData d in data)
132 {
133 PresenceInfo ret = new PresenceInfo();
134
135 ret.UserID = d.UserID;
136 ret.RegionID = d.RegionID;
137
138 info.Add(ret);
139 }
140 }
141
142 // m_log.DebugFormat("[PRESENCE SERVICE]: GetAgents for {0} userIDs found {1} presences", userIDs.Length, info.Count);
143 return info.ToArray();
144 }
145
66 } 146 }
67} 147}
diff --git a/OpenSim/Services/PresenceService/PresenceServiceBase.cs b/OpenSim/Services/PresenceService/PresenceServiceBase.cs
index 60a246b..a4adb2f 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
@@ -77,7 +77,7 @@ namespace OpenSim.Services.PresenceService
77 77
78 m_Database = LoadPlugin<IPresenceData>(dllName, new Object[] { connString, realm }); 78 m_Database = LoadPlugin<IPresenceData>(dllName, new Object[] { connString, realm });
79 if (m_Database == null) 79 if (m_Database == null)
80 throw new Exception("Could not find a storage interface in the given module"); 80 throw new Exception("Could not find a storage interface in the given module " + dllName);
81 81
82 } 82 }
83 } 83 }
diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs
new file mode 100644
index 0000000..697ba63
--- /dev/null
+++ b/OpenSim/Services/UserAccountService/GridUserService.cs
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using Nini.Config;
32using OpenSim.Data;
33using OpenSim.Services.Interfaces;
34using OpenSim.Framework;
35using OpenSim.Framework.Console;
36using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37
38using OpenMetaverse;
39using log4net;
40
41namespace OpenSim.Services.UserAccountService
42{
43 public class GridUserService : GridUserServiceBase, IGridUserService
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 public GridUserService(IConfigSource config) : base(config)
48 {
49 m_log.Debug("[USER GRID SERVICE]: Starting user grid service");
50 }
51
52 public GridUserInfo GetGridUserInfo(string userID)
53 {
54 GridUserData d = m_Database.Get(userID);
55
56 if (d == null)
57 return null;
58
59 GridUserInfo info = new GridUserInfo();
60 info.UserID = d.UserID;
61 info.HomeRegionID = new UUID(d.Data["HomeRegionID"]);
62 info.HomePosition = Vector3.Parse(d.Data["HomePosition"]);
63 info.HomeLookAt = Vector3.Parse(d.Data["HomeLookAt"]);
64
65 info.LastRegionID = new UUID(d.Data["LastRegionID"]);
66 info.LastPosition = Vector3.Parse(d.Data["LastPosition"]);
67 info.LastLookAt = Vector3.Parse(d.Data["LastLookAt"]);
68
69 info.Online = bool.Parse(d.Data["Online"]);
70 info.Login = Util.ToDateTime(Convert.ToInt32(d.Data["Login"]));
71 info.Logout = Util.ToDateTime(Convert.ToInt32(d.Data["Logout"]));
72
73 return info;
74 }
75
76 public GridUserInfo LoggedIn(string userID)
77 {
78 m_log.DebugFormat("[GRID USER SERVICE]: User {0} is online", userID);
79 GridUserData d = m_Database.Get(userID);
80
81 if (d == null)
82 {
83 d = new GridUserData();
84 d.UserID = userID;
85 }
86
87 d.Data["Online"] = true.ToString();
88 d.Data["Login"] = Util.UnixTimeSinceEpoch().ToString();
89
90 m_Database.Store(d);
91
92 return GetGridUserInfo(userID);
93 }
94
95 public bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
96 {
97 m_log.DebugFormat("[GRID USER SERVICE]: User {0} is offline", userID);
98 GridUserData d = m_Database.Get(userID);
99
100 if (d == null)
101 {
102 d = new GridUserData();
103 d.UserID = userID;
104 }
105
106 d.Data["Online"] = false.ToString();
107 d.Data["Logout"] = Util.UnixTimeSinceEpoch().ToString();
108 d.Data["LastRegionID"] = regionID.ToString();
109 d.Data["LastPosition"] = lastPosition.ToString();
110 d.Data["LastLookAt"] = lastLookAt.ToString();
111
112 return m_Database.Store(d);
113 }
114
115 protected bool StoreGridUserInfo(GridUserInfo info)
116 {
117 GridUserData d = new GridUserData();
118
119 d.Data["HomeRegionID"] = info.HomeRegionID.ToString();
120 d.Data["HomePosition"] = info.HomePosition.ToString();
121 d.Data["HomeLookAt"] = info.HomeLookAt.ToString();
122
123 return m_Database.Store(d);
124 }
125
126 public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt)
127 {
128 GridUserData d = m_Database.Get(userID);
129 if (d == null)
130 {
131 d = new GridUserData();
132 d.UserID = userID;
133 }
134
135 d.Data["HomeRegionID"] = homeID.ToString();
136 d.Data["HomePosition"] = homePosition.ToString();
137 d.Data["HomeLookAt"] = homeLookAt.ToString();
138
139 return m_Database.Store(d);
140 }
141
142 public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
143 {
144 //m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID);
145 GridUserData d = m_Database.Get(userID);
146 if (d == null)
147 {
148 d = new GridUserData();
149 d.UserID = userID;
150 }
151
152 d.Data["LastRegionID"] = regionID.ToString();
153 d.Data["LastPosition"] = lastPosition.ToString();
154 d.Data["LastLookAt"] = lastLookAt.ToString();
155
156 return m_Database.Store(d);
157 }
158 }
159} \ No newline at end of file
diff --git a/OpenSim/Services/UserAccountService/GridUserServiceBase.cs b/OpenSim/Services/UserAccountService/GridUserServiceBase.cs
new file mode 100644
index 0000000..990cb63
--- /dev/null
+++ b/OpenSim/Services/UserAccountService/GridUserServiceBase.cs
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using OpenSim.Framework;
32using OpenSim.Data;
33using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base;
35
36namespace OpenSim.Services.UserAccountService
37{
38 public class GridUserServiceBase : ServiceBase
39 {
40 protected IGridUserData m_Database = null;
41
42 public GridUserServiceBase(IConfigSource config) : base(config)
43 {
44 string dllName = String.Empty;
45 string connString = String.Empty;
46 string realm = "GridUser";
47
48 //
49 // Try reading the [DatabaseService] section, if it exists
50 //
51 IConfig dbConfig = config.Configs["DatabaseService"];
52 if (dbConfig != null)
53 {
54 if (dllName == String.Empty)
55 dllName = dbConfig.GetString("StorageProvider", String.Empty);
56 if (connString == String.Empty)
57 connString = dbConfig.GetString("ConnectionString", String.Empty);
58 }
59
60 //
61 // [GridUsetService] section overrides [DatabaseService], if it exists
62 //
63 IConfig presenceConfig = config.Configs["GridUserService"];
64 if (presenceConfig != null)
65 {
66 dllName = presenceConfig.GetString("StorageProvider", dllName);
67 connString = presenceConfig.GetString("ConnectionString", connString);
68 realm = presenceConfig.GetString("Realm", realm);
69 }
70
71 //
72 // We tried, but this doesn't exist. We can't proceed.
73 //
74 if (dllName.Equals(String.Empty))
75 throw new Exception("No StorageProvider configured");
76
77 m_Database = LoadPlugin<IGridUserData>(dllName, new Object[] { connString, realm });
78 if (m_Database == null)
79 throw new Exception("Could not find a storage interface in the given module " + dllName);
80 }
81 }
82} \ No newline at end of file
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
new file mode 100644
index 0000000..6923293
--- /dev/null
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -0,0 +1,399 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using Nini.Config;
32using OpenSim.Data;
33using OpenSim.Services.Interfaces;
34using OpenSim.Framework.Console;
35using GridRegion = OpenSim.Services.Interfaces.GridRegion;
36
37using OpenMetaverse;
38using log4net;
39
40namespace OpenSim.Services.UserAccountService
41{
42 public class UserAccountService : UserAccountServiceBase, IUserAccountService
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private static UserAccountService m_RootInstance;
46
47 protected IGridService m_GridService;
48 protected IAuthenticationService m_AuthenticationService;
49 protected IGridUserService m_GridUserService;
50 protected IInventoryService m_InventoryService;
51
52 public UserAccountService(IConfigSource config)
53 : base(config)
54 {
55 IConfig userConfig = config.Configs["UserAccountService"];
56 if (userConfig == null)
57 throw new Exception("No UserAccountService configuration");
58
59 // In case there are several instances of this class in the same process,
60 // the console commands are only registered for the root instance
61 if (m_RootInstance == null)
62 {
63 m_RootInstance = this;
64 string gridServiceDll = userConfig.GetString("GridService", string.Empty);
65 if (gridServiceDll != string.Empty)
66 m_GridService = LoadPlugin<IGridService>(gridServiceDll, new Object[] { config });
67
68 string authServiceDll = userConfig.GetString("AuthenticationService", string.Empty);
69 if (authServiceDll != string.Empty)
70 m_AuthenticationService = LoadPlugin<IAuthenticationService>(authServiceDll, new Object[] { config });
71
72 string presenceServiceDll = userConfig.GetString("GridUserService", string.Empty);
73 if (presenceServiceDll != string.Empty)
74 m_GridUserService = LoadPlugin<IGridUserService>(presenceServiceDll, new Object[] { config });
75
76 string invServiceDll = userConfig.GetString("InventoryService", string.Empty);
77 if (invServiceDll != string.Empty)
78 m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
79
80 if (MainConsole.Instance != null)
81 {
82 MainConsole.Instance.Commands.AddCommand("UserService", false,
83 "create user",
84 "create user [<first> [<last> [<pass> [<email>]]]]",
85 "Create a new user", HandleCreateUser);
86 MainConsole.Instance.Commands.AddCommand("UserService", false, "reset user password",
87 "reset user password [<first> [<last> [<password>]]]",
88 "Reset a user password", HandleResetUserPassword);
89 }
90
91 }
92
93 }
94
95 #region IUserAccountService
96
97 public UserAccount GetUserAccount(UUID scopeID, string firstName,
98 string lastName)
99 {
100 UserAccountData[] d;
101
102 if (scopeID != UUID.Zero)
103 {
104 d = m_Database.Get(
105 new string[] { "ScopeID", "FirstName", "LastName" },
106 new string[] { scopeID.ToString(), firstName, lastName });
107 if (d.Length < 1)
108 {
109 d = m_Database.Get(
110 new string[] { "ScopeID", "FirstName", "LastName" },
111 new string[] { UUID.Zero.ToString(), firstName, lastName });
112 }
113 }
114 else
115 {
116 d = m_Database.Get(
117 new string[] { "FirstName", "LastName" },
118 new string[] { firstName, lastName });
119 }
120
121 if (d.Length < 1)
122 return null;
123
124 return MakeUserAccount(d[0]);
125 }
126
127 private UserAccount MakeUserAccount(UserAccountData d)
128 {
129 UserAccount u = new UserAccount();
130 u.FirstName = d.FirstName;
131 u.LastName = d.LastName;
132 u.PrincipalID = d.PrincipalID;
133 u.ScopeID = d.ScopeID;
134 if (d.Data.ContainsKey("Email") && d.Data["Email"] != null)
135 u.Email = d.Data["Email"].ToString();
136 else
137 u.Email = string.Empty;
138 u.Created = Convert.ToInt32(d.Data["Created"].ToString());
139 if (d.Data.ContainsKey("UserTitle") && d.Data["UserTitle"] != null)
140 u.UserTitle = d.Data["UserTitle"].ToString();
141 else
142 u.UserTitle = string.Empty;
143 if (d.Data.ContainsKey("UserLevel") && d.Data["UserLevel"] != null)
144 Int32.TryParse(d.Data["UserLevel"], out u.UserLevel);
145 if (d.Data.ContainsKey("UserFlags") && d.Data["UserFlags"] != null)
146 Int32.TryParse(d.Data["UserFlags"], out u.UserFlags);
147
148 if (d.Data.ContainsKey("ServiceURLs") && d.Data["ServiceURLs"] != null)
149 {
150 string[] URLs = d.Data["ServiceURLs"].ToString().Split(new char[] { ' ' });
151 u.ServiceURLs = new Dictionary<string, object>();
152
153 foreach (string url in URLs)
154 {
155 string[] parts = url.Split(new char[] { '=' });
156
157 if (parts.Length != 2)
158 continue;
159
160 string name = System.Web.HttpUtility.UrlDecode(parts[0]);
161 string val = System.Web.HttpUtility.UrlDecode(parts[1]);
162
163 u.ServiceURLs[name] = val;
164 }
165 }
166 else
167 u.ServiceURLs = new Dictionary<string, object>();
168
169 return u;
170 }
171
172 public UserAccount GetUserAccount(UUID scopeID, string email)
173 {
174 UserAccountData[] d;
175
176 if (scopeID != UUID.Zero)
177 {
178 d = m_Database.Get(
179 new string[] { "ScopeID", "Email" },
180 new string[] { scopeID.ToString(), email });
181 if (d.Length < 1)
182 {
183 d = m_Database.Get(
184 new string[] { "ScopeID", "Email" },
185 new string[] { UUID.Zero.ToString(), email });
186 }
187 }
188 else
189 {
190 d = m_Database.Get(
191 new string[] { "Email" },
192 new string[] { email });
193 }
194
195 if (d.Length < 1)
196 return null;
197
198 return MakeUserAccount(d[0]);
199 }
200
201 public UserAccount GetUserAccount(UUID scopeID, UUID principalID)
202 {
203 UserAccountData[] d;
204
205 if (scopeID != UUID.Zero)
206 {
207 d = m_Database.Get(
208 new string[] { "ScopeID", "PrincipalID" },
209 new string[] { scopeID.ToString(), principalID.ToString() });
210 if (d.Length < 1)
211 {
212 d = m_Database.Get(
213 new string[] { "ScopeID", "PrincipalID" },
214 new string[] { UUID.Zero.ToString(), principalID.ToString() });
215 }
216 }
217 else
218 {
219 d = m_Database.Get(
220 new string[] { "PrincipalID" },
221 new string[] { principalID.ToString() });
222 }
223
224 if (d.Length < 1)
225 {
226 return null;
227 }
228
229 return MakeUserAccount(d[0]);
230 }
231
232 public bool StoreUserAccount(UserAccount data)
233 {
234 UserAccountData d = new UserAccountData();
235
236 d.FirstName = data.FirstName;
237 d.LastName = data.LastName;
238 d.PrincipalID = data.PrincipalID;
239 d.ScopeID = data.ScopeID;
240 d.Data = new Dictionary<string, string>();
241 d.Data["Email"] = data.Email;
242 d.Data["Created"] = data.Created.ToString();
243 d.Data["UserLevel"] = data.UserLevel.ToString();
244 d.Data["UserFlags"] = data.UserFlags.ToString();
245 if (data.UserTitle != null)
246 d.Data["UserTitle"] = data.UserTitle.ToString();
247
248 List<string> parts = new List<string>();
249
250 foreach (KeyValuePair<string, object> kvp in data.ServiceURLs)
251 {
252 string key = System.Web.HttpUtility.UrlEncode(kvp.Key);
253 string val = System.Web.HttpUtility.UrlEncode(kvp.Value.ToString());
254 parts.Add(key + "=" + val);
255 }
256
257 d.Data["ServiceURLs"] = string.Join(" ", parts.ToArray());
258
259 return m_Database.Store(d);
260 }
261
262 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
263 {
264 UserAccountData[] d = m_Database.GetUsers(scopeID, query);
265
266 if (d == null)
267 return new List<UserAccount>();
268
269 List<UserAccount> ret = new List<UserAccount>();
270
271 foreach (UserAccountData data in d)
272 ret.Add(MakeUserAccount(data));
273
274 return ret;
275 }
276
277 #endregion
278
279 #region Console commands
280 /// <summary>
281 /// Create a new user
282 /// </summary>
283 /// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email</param>
284 protected void HandleCreateUser(string module, string[] cmdparams)
285 {
286 string firstName;
287 string lastName;
288 string password;
289 string email;
290
291 if (cmdparams.Length < 3)
292 firstName = MainConsole.Instance.CmdPrompt("First name", "Default");
293 else firstName = cmdparams[2];
294
295 if (cmdparams.Length < 4)
296 lastName = MainConsole.Instance.CmdPrompt("Last name", "User");
297 else lastName = cmdparams[3];
298
299 if (cmdparams.Length < 5)
300 password = MainConsole.Instance.PasswdPrompt("Password");
301 else password = cmdparams[4];
302
303 if (cmdparams.Length < 6)
304 email = MainConsole.Instance.CmdPrompt("Email", "");
305 else email = cmdparams[5];
306
307 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
308 if (null == account)
309 {
310 account = new UserAccount(UUID.Zero, firstName, lastName, email);
311 if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
312 {
313 account.ServiceURLs = new Dictionary<string, object>();
314 account.ServiceURLs["HomeURI"] = string.Empty;
315 account.ServiceURLs["GatekeeperURI"] = string.Empty;
316 account.ServiceURLs["InventoryServerURI"] = string.Empty;
317 account.ServiceURLs["AssetServerURI"] = string.Empty;
318 }
319
320 if (StoreUserAccount(account))
321 {
322 bool success = false;
323 if (m_AuthenticationService != null)
324 success = m_AuthenticationService.SetPassword(account.PrincipalID, password);
325 if (!success)
326 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.",
327 firstName, lastName);
328
329 GridRegion home = null;
330 if (m_GridService != null)
331 {
332 List<GridRegion> defaultRegions = m_GridService.GetDefaultRegions(UUID.Zero);
333 if (defaultRegions != null && defaultRegions.Count >= 1)
334 home = defaultRegions[0];
335
336 if (m_GridUserService != null && home != null)
337 m_GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
338 else
339 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.",
340 firstName, lastName);
341
342 }
343 else
344 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.",
345 firstName, lastName);
346
347 if (m_InventoryService != null)
348 success = m_InventoryService.CreateUserInventory(account.PrincipalID);
349 if (!success)
350 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
351 firstName, lastName);
352
353
354 m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName);
355 }
356 }
357 else
358 {
359 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
360 }
361
362 }
363
364 protected void HandleResetUserPassword(string module, string[] cmdparams)
365 {
366 string firstName;
367 string lastName;
368 string newPassword;
369
370 if (cmdparams.Length < 4)
371 firstName = MainConsole.Instance.CmdPrompt("First name");
372 else firstName = cmdparams[3];
373
374 if (cmdparams.Length < 5)
375 lastName = MainConsole.Instance.CmdPrompt("Last name");
376 else lastName = cmdparams[4];
377
378 if (cmdparams.Length < 6)
379 newPassword = MainConsole.Instance.PasswdPrompt("New password");
380 else newPassword = cmdparams[5];
381
382 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
383 if (account == null)
384 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: No such user");
385
386 bool success = false;
387 if (m_AuthenticationService != null)
388 success = m_AuthenticationService.SetPassword(account.PrincipalID, newPassword);
389 if (!success)
390 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Unable to reset password for account {0} {1}.",
391 firstName, lastName);
392 else
393 m_log.InfoFormat("[USER ACCOUNT SERVICE]: Password reset for user {0} {1}", firstName, lastName);
394 }
395
396 #endregion
397
398 }
399}
diff --git a/OpenSim/Services/UserService/UserServiceBase.cs b/OpenSim/Services/UserAccountService/UserAccountServiceBase.cs
index fea8b01..c1a7b76 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