aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services')
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs5
-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.cs397
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs216
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs373
-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.cs587
-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.cs601
-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.cs286
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs641
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs322
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs243
-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)59
-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.cs62
-rw-r--r--OpenSim/Services/Interfaces/ISimulationService.cs27
-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.cs70
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs977
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs801
-rw-r--r--OpenSim/Services/PresenceService/PresenceService.cs108
-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, 12970 insertions, 719 deletions
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index ed87f3f..4e512e7 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)
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..a29ac28
--- /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.Message);
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..3e91e3a
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -0,0 +1,397 @@
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 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
208 {
209 position = Vector3.UnitY; lookAt = Vector3.UnitY;
210
211 Hashtable hash = new Hashtable();
212 hash["userID"] = userID.ToString();
213
214 IList paramList = new ArrayList();
215 paramList.Add(hash);
216
217 XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList);
218 XmlRpcResponse response = null;
219 try
220 {
221 response = request.Send(m_ServerURL, 10000);
222 }
223 catch (Exception e)
224 {
225 return null;
226 }
227
228 if (response.IsFault)
229 {
230 return null;
231 }
232
233 hash = (Hashtable)response.Value;
234 //foreach (Object o in hash)
235 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
236 try
237 {
238 bool success = false;
239 Boolean.TryParse((string)hash["result"], out success);
240 if (success)
241 {
242 GridRegion region = new GridRegion();
243
244 UUID.TryParse((string)hash["uuid"], out region.RegionID);
245 //m_log.Debug(">> HERE, uuid: " + region.RegionID);
246 int n = 0;
247 if (hash["x"] != null)
248 {
249 Int32.TryParse((string)hash["x"], out n);
250 region.RegionLocX = n;
251 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
252 }
253 if (hash["y"] != null)
254 {
255 Int32.TryParse((string)hash["y"], out n);
256 region.RegionLocY = n;
257 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
258 }
259 if (hash["region_name"] != null)
260 {
261 region.RegionName = (string)hash["region_name"];
262 //m_log.Debug(">> HERE, name: " + region.RegionName);
263 }
264 if (hash["hostname"] != null)
265 region.ExternalHostName = (string)hash["hostname"];
266 if (hash["http_port"] != null)
267 {
268 uint p = 0;
269 UInt32.TryParse((string)hash["http_port"], out p);
270 region.HttpPort = p;
271 }
272 if (hash["internal_port"] != null)
273 {
274 int p = 0;
275 Int32.TryParse((string)hash["internal_port"], out p);
276 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
277 }
278 if (hash["position"] != null)
279 Vector3.TryParse((string)hash["position"], out position);
280 if (hash["lookAt"] != null)
281 Vector3.TryParse((string)hash["lookAt"], out lookAt);
282
283 // Successful return
284 return region;
285 }
286
287 }
288 catch (Exception e)
289 {
290 return null;
291 }
292
293 return null;
294
295 }
296
297 public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName)
298 {
299 Hashtable hash = new Hashtable();
300 hash["sessionID"] = sessionID.ToString();
301 hash["externalName"] = thisGridExternalName;
302
303 IList paramList = new ArrayList();
304 paramList.Add(hash);
305
306 XmlRpcRequest request = new XmlRpcRequest("agent_is_coming_home", paramList);
307 string reason = string.Empty;
308 return GetBoolResponse(request, out reason);
309 }
310
311 public bool VerifyAgent(UUID sessionID, string token)
312 {
313 Hashtable hash = new Hashtable();
314 hash["sessionID"] = sessionID.ToString();
315 hash["token"] = token;
316
317 IList paramList = new ArrayList();
318 paramList.Add(hash);
319
320 XmlRpcRequest request = new XmlRpcRequest("verify_agent", paramList);
321 string reason = string.Empty;
322 return GetBoolResponse(request, out reason);
323 }
324
325 public bool VerifyClient(UUID sessionID, string token)
326 {
327 Hashtable hash = new Hashtable();
328 hash["sessionID"] = sessionID.ToString();
329 hash["token"] = token;
330
331 IList paramList = new ArrayList();
332 paramList.Add(hash);
333
334 XmlRpcRequest request = new XmlRpcRequest("verify_client", paramList);
335 string reason = string.Empty;
336 return GetBoolResponse(request, out reason);
337 }
338
339 public void LogoutAgent(UUID userID, UUID sessionID)
340 {
341 Hashtable hash = new Hashtable();
342 hash["sessionID"] = sessionID.ToString();
343 hash["userID"] = userID.ToString();
344
345 IList paramList = new ArrayList();
346 paramList.Add(hash);
347
348 XmlRpcRequest request = new XmlRpcRequest("logout_agent", paramList);
349 string reason = string.Empty;
350 GetBoolResponse(request, out reason);
351 }
352
353
354 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
355 {
356 //m_log.Debug("[HGrid]: Linking to " + uri);
357 XmlRpcResponse response = null;
358 try
359 {
360 response = request.Send(m_ServerURL, 10000);
361 }
362 catch (Exception e)
363 {
364 m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server ");
365 reason = "Exception: " + e.Message;
366 return false;
367 }
368
369 if (response.IsFault)
370 {
371 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
372 reason = "XMLRPC Fault";
373 return false;
374 }
375
376 Hashtable hash = (Hashtable)response.Value;
377 //foreach (Object o in hash)
378 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
379 try
380 {
381 bool success = false;
382 reason = string.Empty;
383 Boolean.TryParse((string)hash["result"], out success);
384
385 return success;
386 }
387 catch (Exception e)
388 {
389 m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace);
390 reason = "Exception: " + e.Message;
391 return false;
392 }
393
394 }
395
396 }
397}
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..41ebeaf
--- /dev/null
+++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
@@ -0,0 +1,373 @@
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 }
304
305 return pinfo;
306 }
307
308 public PresenceInfo[] GetAgents(string[] userIDs)
309 {
310 Dictionary<string, object> sendData = new Dictionary<string, object>();
311 //sendData["SCOPEID"] = scopeID.ToString();
312 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
313 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
314 sendData["METHOD"] = "getagents";
315
316 sendData["uuids"] = new List<string>(userIDs);
317
318 string reply = string.Empty;
319 string reqString = ServerUtils.BuildQueryString(sendData);
320 //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
321 try
322 {
323 reply = SynchronousRestFormsRequester.MakeRequest("POST",
324 m_ServerURI + "/presence",
325 reqString);
326 if (reply == null || (reply != null && reply == string.Empty))
327 {
328 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply");
329 return null;
330 }
331 }
332 catch (Exception e)
333 {
334 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
335 }
336
337 List<PresenceInfo> rinfos = new List<PresenceInfo>();
338
339 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
340
341 if (replyData != null)
342 {
343 if (replyData.ContainsKey("result") &&
344 (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure"))
345 {
346 return new PresenceInfo[0];
347 }
348
349 Dictionary<string, object>.ValueCollection pinfosList = replyData.Values;
350 //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
351 foreach (object presence in pinfosList)
352 {
353 if (presence is Dictionary<string, object>)
354 {
355 PresenceInfo pinfo = new PresenceInfo((Dictionary<string, object>)presence);
356 rinfos.Add(pinfo);
357 }
358 else
359 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}",
360 presence.GetType());
361 }
362 }
363 else
364 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response");
365
366 return rinfos.ToArray();
367 }
368
369
370 #endregion
371
372 }
373}
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..e48b7de
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
@@ -0,0 +1,587 @@
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.Online = true;
515 info.UserID = sessionResponse["UserID"].AsUUID().ToString();
516 info.RegionID = sessionResponse["SceneID"].AsUUID();
517 info.Position = sessionResponse["ScenePosition"].AsVector3();
518 info.LookAt = sessionResponse["SceneLookAt"].AsVector3();
519
520 if (userResponse != null && userResponse["User"] is OSDMap)
521 {
522 OSDMap user = (OSDMap)userResponse["User"];
523
524 info.Login = user["LastLoginDate"].AsDate();
525 info.Logout = user["LastLogoutDate"].AsDate();
526 DeserializeLocation(user["HomeLocation"].AsString(), out info.HomeRegionID, out info.HomePosition, out info.HomeLookAt);
527 }
528
529 return info;
530 }
531
532 private GridUserInfo ResponseToGridUserInfo(OSDMap userResponse)
533 {
534 if (userResponse != null && userResponse["User"] is OSDMap)
535 {
536
537 GridUserInfo info = new GridUserInfo();
538
539 info.Online = true;
540 info.UserID = userResponse["UserID"].AsUUID().ToString();
541 info.LastRegionID = userResponse["SceneID"].AsUUID();
542 info.LastPosition = userResponse["ScenePosition"].AsVector3();
543 info.LastLookAt = userResponse["SceneLookAt"].AsVector3();
544
545 OSDMap user = (OSDMap)userResponse["User"];
546
547 info.Login = user["LastLoginDate"].AsDate();
548 info.Logout = user["LastLogoutDate"].AsDate();
549 DeserializeLocation(user["HomeLocation"].AsString(), out info.HomeRegionID, out info.HomePosition, out info.HomeLookAt);
550
551 return info;
552 }
553
554 return null;
555 }
556
557 private string SerializeLocation(UUID regionID, Vector3 position, Vector3 lookAt)
558 {
559 return "{" + String.Format("\"SceneID\":\"{0}\",\"Position\":\"{1}\",\"LookAt\":\"{2}\"", regionID, position, lookAt) + "}";
560 }
561
562 private bool DeserializeLocation(string location, out UUID regionID, out Vector3 position, out Vector3 lookAt)
563 {
564 OSDMap map = null;
565
566 try { map = OSDParser.DeserializeJson(location) as OSDMap; }
567 catch { }
568
569 if (map != null)
570 {
571 regionID = map["SceneID"].AsUUID();
572 if (Vector3.TryParse(map["Position"].AsString(), out position) &&
573 Vector3.TryParse(map["LookAt"].AsString(), out lookAt))
574 {
575 return true;
576 }
577 }
578
579 regionID = UUID.Zero;
580 position = Vector3.Zero;
581 lookAt = Vector3.Zero;
582 return false;
583 }
584
585 #endregion Helpers
586 }
587}
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..ff0dd7e
--- /dev/null
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -0,0 +1,601 @@
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 public bool CloseAgent(GridRegion destination, UUID id)
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 request.Timeout = 10000;
463
464 StreamReader sr = null;
465 try
466 {
467 WebResponse webResponse = request.GetResponse();
468 if (webResponse == null)
469 {
470 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent delete ");
471 }
472
473 sr = new StreamReader(webResponse.GetResponseStream());
474 //reply = sr.ReadToEnd().Trim();
475 sr.ReadToEnd().Trim();
476 sr.Close();
477 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
478
479 }
480 catch (WebException ex)
481 {
482 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent delete {0}", ex.Message);
483 return false;
484 }
485 finally
486 {
487 if (sr != null)
488 sr.Close();
489 }
490
491 return true;
492 }
493
494 #endregion Agents
495
496 #region Objects
497
498 protected virtual string ObjectPath()
499 {
500 return "/object/";
501 }
502
503 public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
504 {
505 string uri
506 = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + ObjectPath() + sog.UUID + "/";
507 //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri);
508
509 WebRequest ObjectCreateRequest = WebRequest.Create(uri);
510 ObjectCreateRequest.Method = "POST";
511 ObjectCreateRequest.ContentType = "application/json";
512 ObjectCreateRequest.Timeout = 10000;
513
514 OSDMap args = new OSDMap(2);
515 args["sog"] = OSD.FromString(sog.ToXml2());
516 args["extra"] = OSD.FromString(sog.ExtraToXmlString());
517 string state = sog.GetStateSnapshot();
518 if (state.Length > 0)
519 args["state"] = OSD.FromString(state);
520 // Add the input general arguments
521 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
522 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
523 args["destination_name"] = OSD.FromString(destination.RegionName);
524 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
525
526 string strBuffer = "";
527 byte[] buffer = new byte[1];
528 try
529 {
530 strBuffer = OSDParser.SerializeJsonString(args);
531 Encoding str = Util.UTF8;
532 buffer = str.GetBytes(strBuffer);
533
534 }
535 catch (Exception e)
536 {
537 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of CreateObject: {0}", e.Message);
538 // ignore. buffer will be empty, caller should check.
539 }
540
541 Stream os = null;
542 try
543 { // send the Post
544 ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
545 os = ObjectCreateRequest.GetRequestStream();
546 os.Write(buffer, 0, strBuffer.Length); //Send it
547 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateObject request to remote sim {0}", uri);
548 }
549 catch (WebException ex)
550 {
551 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on CreateObject {0}", ex.Message);
552 return false;
553 }
554 finally
555 {
556 if (os != null)
557 os.Close();
558 }
559
560 // Let's wait for the response
561 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
562
563 StreamReader sr = null;
564 try
565 {
566 WebResponse webResponse = ObjectCreateRequest.GetResponse();
567 if (webResponse == null)
568 {
569 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on CreateObject post");
570 return false;
571 }
572
573 sr = new StreamReader(webResponse.GetResponseStream());
574 //reply = sr.ReadToEnd().Trim();
575 sr.ReadToEnd().Trim();
576 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", reply);
577
578 }
579 catch (WebException ex)
580 {
581 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of CreateObject {0}", ex.Message);
582 return false;
583 }
584 finally
585 {
586 if (sr != null)
587 sr.Close();
588 }
589
590 return true;
591 }
592
593 public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
594 {
595 // TODO, not that urgent
596 return false;
597 }
598
599 #endregion Objects
600 }
601}
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..4089fce 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;
@@ -194,6 +331,13 @@ namespace OpenSim.Services.GridService
194 } 331 }
195 } 332 }
196 333
334 if (m_AllowHypergridMapSearch && (rdatas == null || (rdatas != null && rdatas.Count == 0) && name.Contains(".")))
335 {
336 GridRegion r = m_HypergridLinker.LinkRegion(scopeID, name);
337 if (r != null)
338 rinfos.Add(r);
339 }
340
197 return rinfos; 341 return rinfos;
198 } 342 }
199 343
@@ -216,7 +360,7 @@ namespace OpenSim.Services.GridService
216 360
217 #region Data structure conversions 361 #region Data structure conversions
218 362
219 protected RegionData RegionInfo2RegionData(GridRegion rinfo) 363 public RegionData RegionInfo2RegionData(GridRegion rinfo)
220 { 364 {
221 RegionData rdata = new RegionData(); 365 RegionData rdata = new RegionData();
222 rdata.posX = (int)rinfo.RegionLocX; 366 rdata.posX = (int)rinfo.RegionLocX;
@@ -229,7 +373,7 @@ namespace OpenSim.Services.GridService
229 return rdata; 373 return rdata;
230 } 374 }
231 375
232 protected GridRegion RegionData2RegionInfo(RegionData rdata) 376 public GridRegion RegionData2RegionInfo(RegionData rdata)
233 { 377 {
234 GridRegion rinfo = new GridRegion(rdata.Data); 378 GridRegion rinfo = new GridRegion(rdata.Data);
235 rinfo.RegionLocX = rdata.posX; 379 rinfo.RegionLocX = rdata.posX;
@@ -243,5 +387,143 @@ namespace OpenSim.Services.GridService
243 387
244 #endregion 388 #endregion
245 389
390 public List<GridRegion> GetDefaultRegions(UUID scopeID)
391 {
392 List<GridRegion> ret = new List<GridRegion>();
393
394 List<RegionData> regions = m_Database.GetDefaultRegions(scopeID);
395
396 foreach (RegionData r in regions)
397 {
398 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
399 ret.Add(RegionData2RegionInfo(r));
400 }
401
402 m_log.DebugFormat("[GRID SERVICE]: GetDefaultRegions returning {0} regions", ret.Count);
403 return ret;
404 }
405
406 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
407 {
408 List<GridRegion> ret = new List<GridRegion>();
409
410 List<RegionData> regions = m_Database.GetFallbackRegions(scopeID, x, y);
411
412 foreach (RegionData r in regions)
413 {
414 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Data.RegionFlags.RegionOnline) != 0)
415 ret.Add(RegionData2RegionInfo(r));
416 }
417
418 m_log.DebugFormat("[GRID SERVICE]: Fallback returned {0} regions", ret.Count);
419 return ret;
420 }
421
422 public int GetRegionFlags(UUID scopeID, UUID regionID)
423 {
424 RegionData region = m_Database.Get(regionID, scopeID);
425
426 if (region != null)
427 {
428 int flags = Convert.ToInt32(region.Data["flags"]);
429 //m_log.DebugFormat("[GRID SERVICE]: Request for flags of {0}: {1}", regionID, flags);
430 return flags;
431 }
432 else
433 return -1;
434 }
435
436 private void HandleShowRegion(string module, string[] cmd)
437 {
438 if (cmd.Length != 3)
439 {
440 MainConsole.Instance.Output("Syntax: show region <region name>");
441 return;
442 }
443 List<RegionData> regions = m_Database.Get(cmd[2], UUID.Zero);
444 if (regions == null || regions.Count < 1)
445 {
446 MainConsole.Instance.Output("Region not found");
447 return;
448 }
449
450 MainConsole.Instance.Output("Region Name Region UUID");
451 MainConsole.Instance.Output("Location URI");
452 MainConsole.Instance.Output("Owner ID Flags");
453 MainConsole.Instance.Output("-------------------------------------------------------------------------------");
454 foreach (RegionData r in regions)
455 {
456 OpenSim.Data.RegionFlags flags = (OpenSim.Data.RegionFlags)Convert.ToInt32(r.Data["flags"]);
457 MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} {5}\n\n",
458 r.RegionName, r.RegionID,
459 String.Format("{0},{1}", r.posX, r.posY), "http://" + r.Data["serverIP"].ToString() + ":" + r.Data["serverPort"].ToString(),
460 r.Data["owner_uuid"].ToString(), flags.ToString()));
461 }
462 return;
463 }
464
465 private int ParseFlags(int prev, string flags)
466 {
467 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)prev;
468
469 string[] parts = flags.Split(new char[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
470
471 foreach (string p in parts)
472 {
473 int val;
474
475 try
476 {
477 if (p.StartsWith("+"))
478 {
479 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
480 f |= (OpenSim.Data.RegionFlags)val;
481 }
482 else if (p.StartsWith("-"))
483 {
484 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p.Substring(1));
485 f &= ~(OpenSim.Data.RegionFlags)val;
486 }
487 else
488 {
489 val = (int)Enum.Parse(typeof(OpenSim.Data.RegionFlags), p);
490 f |= (OpenSim.Data.RegionFlags)val;
491 }
492 }
493 catch (Exception)
494 {
495 MainConsole.Instance.Output("Error in flag specification: " + p);
496 }
497 }
498
499 return (int)f;
500 }
501
502 private void HandleSetFlags(string module, string[] cmd)
503 {
504 if (cmd.Length < 5)
505 {
506 MainConsole.Instance.Output("Syntax: set region flags <region name> <flags>");
507 return;
508 }
509
510 List<RegionData> regions = m_Database.Get(cmd[3], UUID.Zero);
511 if (regions == null || regions.Count < 1)
512 {
513 MainConsole.Instance.Output("Region not found");
514 return;
515 }
516
517 foreach (RegionData r in regions)
518 {
519 int flags = Convert.ToInt32(r.Data["flags"]);
520 flags = ParseFlags(flags, cmd[4]);
521 r.Data["flags"] = flags.ToString();
522 OpenSim.Data.RegionFlags f = (OpenSim.Data.RegionFlags)flags;
523
524 MainConsole.Instance.Output(String.Format("Set region {0} to {1}", r.RegionName, f));
525 m_Database.Store(r);
526 }
527 }
246 } 528 }
247} 529}
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..3af7ef9
--- /dev/null
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -0,0 +1,243 @@
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 TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region)
152 {
153 TravelingAgentInfo travel = new TravelingAgentInfo();
154 TravelingAgentInfo old = null;
155 lock (m_TravelingAgents)
156 {
157 if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID))
158 {
159 old = m_TravelingAgents[agentCircuit.SessionID];
160 }
161
162 m_TravelingAgents[agentCircuit.SessionID] = travel;
163 }
164 travel.UserID = agentCircuit.AgentID;
165 travel.GridExternalName = region.ExternalHostName + ":" + region.HttpPort;
166 travel.ServiceToken = agentCircuit.ServiceSessionID;
167 if (old != null)
168 travel.ClientToken = old.ClientToken;
169
170 return old;
171 }
172
173 public void LogoutAgent(UUID userID, UUID sessionID)
174 {
175 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
176
177 lock (m_TravelingAgents)
178 {
179 List<UUID> travels = new List<UUID>();
180 foreach (KeyValuePair<UUID, TravelingAgentInfo> kvp in m_TravelingAgents)
181 if (kvp.Value == null) // do some clean up
182 travels.Add(kvp.Key);
183 else if (kvp.Value.UserID == userID)
184 travels.Add(kvp.Key);
185 foreach (UUID session in travels)
186 m_TravelingAgents.Remove(session);
187 }
188 }
189
190 // We need to prevent foreign users with the same UUID as a local user
191 public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName)
192 {
193 if (!m_TravelingAgents.ContainsKey(sessionID))
194 return false;
195
196 TravelingAgentInfo travel = m_TravelingAgents[sessionID];
197 return travel.GridExternalName == thisGridExternalName;
198 }
199
200 public bool VerifyClient(UUID sessionID, string token)
201 {
202 return true;
203
204 // Commenting this for now until I understand better what part of a sender's
205 // info stays unchanged throughout a session
206 //
207 //if (m_TravelingAgents.ContainsKey(sessionID))
208 //{
209 // // Aquiles heel. Must trust the first grid upon login
210 // if (m_TravelingAgents[sessionID].ClientToken == string.Empty)
211 // {
212 // m_TravelingAgents[sessionID].ClientToken = token;
213 // return true;
214 // }
215 // return m_TravelingAgents[sessionID].ClientToken == token;
216 //}
217 //return false;
218 }
219
220 public bool VerifyAgent(UUID sessionID, string token)
221 {
222 if (m_TravelingAgents.ContainsKey(sessionID))
223 {
224 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken);
225 return m_TravelingAgents[sessionID].ServiceToken == token;
226 }
227
228 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
229
230 return false;
231 }
232
233 }
234
235 class TravelingAgentInfo
236 {
237 public UUID UserID;
238 public string GridExternalName = string.Empty;
239 public string ServiceToken = string.Empty;
240 public string ClientToken = string.Empty;
241 }
242
243}
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..2692c48
--- /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["PricipalID"] = 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..ca7b9b3 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,34 @@
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 45
65 public bool CreateUserAccount(UserAccount data, UUID principalID, string token) 46 /// <summary>
66 { 47 /// HG1.5 only
67 return false; 48 /// </summary>
68 } 49 public interface IUserAgentService
50 {
51 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
52 void LogoutAgent(UUID userID, UUID sessionID);
53 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
69 54
70 public List<UserAccount> GetUserAccount(UUID scopeID, 55 bool AgentIsComingHome(UUID sessionID, string thisGridExternalName);
71 string query) 56 bool VerifyAgent(UUID sessionID, string token);
72 { 57 bool VerifyClient(UUID sessionID, string token);
73 return null;
74 }
75 } 58 }
76} 59}
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..abbae2c 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,68 @@ namespace OpenSim.Services.Interfaces
33{ 34{
34 public class PresenceInfo 35 public class PresenceInfo
35 { 36 {
36 public UUID PrincipalID; 37 public string UserID;
37 public UUID RegionID; 38 public UUID RegionID;
38 public Dictionary<string, string> Data; 39 public bool Online;
40 public DateTime Login;
41 public DateTime Logout;
42 public Vector3 Position;
43 public Vector3 LookAt;
44 public UUID HomeRegionID;
45 public Vector3 HomePosition;
46 public Vector3 HomeLookAt;
47
48 public PresenceInfo()
49 {
50 }
51
52 public PresenceInfo(Dictionary<string, object> kvp)
53 {
54 if (kvp.ContainsKey("UserID"))
55 UserID = kvp["UserID"].ToString();
56 if (kvp.ContainsKey("RegionID"))
57 UUID.TryParse(kvp["RegionID"].ToString(), out RegionID);
58 }
59
60 public Dictionary<string, object> ToKeyValuePairs()
61 {
62 Dictionary<string, object> result = new Dictionary<string, object>();
63 result["UserID"] = UserID;
64 result["RegionID"] = RegionID.ToString();
65
66 return result;
67 }
68
69 public static PresenceInfo[] GetOnlinePresences(PresenceInfo[] pinfos)
70 {
71 if (pinfos == null)
72 return null;
73
74 List<PresenceInfo> lst = new List<PresenceInfo>(pinfos);
75 lst = lst.FindAll(delegate(PresenceInfo each) { return each.Online; });
76
77 return lst.ToArray();
78 }
79
80 public static PresenceInfo GetOnlinePresence(PresenceInfo[] pinfos)
81 {
82 pinfos = GetOnlinePresences(pinfos);
83 if (pinfos != null && pinfos.Length >= 1)
84 return pinfos[0];
85
86 return null;
87 }
39 } 88 }
40 89
41 public interface IPresenceService 90 public interface IPresenceService
42 { 91 {
43 bool Report(PresenceInfo presence); 92 bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID);
93 bool LogoutAgent(UUID sessionID);
94 bool LogoutRegionAgents(UUID regionID);
95
96 bool ReportAgent(UUID sessionID, UUID regionID);
97
98 PresenceInfo GetAgent(UUID sessionID);
99 PresenceInfo[] GetAgents(string[] userIDs);
44 } 100 }
45} 101}
diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs
index a169ab7..67d7cbe 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,7 @@ 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);
67 72
68 /// <summary> 73 /// <summary>
69 /// Close agent. 74 /// Close agent.
@@ -71,7 +76,7 @@ namespace OpenSim.Services.Interfaces
71 /// <param name="regionHandle"></param> 76 /// <param name="regionHandle"></param>
72 /// <param name="id"></param> 77 /// <param name="id"></param>
73 /// <returns></returns> 78 /// <returns></returns>
74 bool CloseAgent(ulong regionHandle, UUID id); 79 bool CloseAgent(GridRegion destination, UUID id);
75 80
76 #endregion Agents 81 #endregion Agents
77 82
@@ -84,7 +89,7 @@ namespace OpenSim.Services.Interfaces
84 /// <param name="sog"></param> 89 /// <param name="sog"></param>
85 /// <param name="isLocalCall"></param> 90 /// <param name="isLocalCall"></param>
86 /// <returns></returns> 91 /// <returns></returns>
87 bool CreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall); 92 bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall);
88 93
89 /// <summary> 94 /// <summary>
90 /// Create an object from the user's inventory in the destination region. 95 /// Create an object from the user's inventory in the destination region.
@@ -94,15 +99,9 @@ namespace OpenSim.Services.Interfaces
94 /// <param name="userID"></param> 99 /// <param name="userID"></param>
95 /// <param name="itemID"></param> 100 /// <param name="itemID"></param>
96 /// <returns></returns> 101 /// <returns></returns>
97 bool CreateObject(ulong regionHandle, UUID userID, UUID itemID); 102 bool CreateObject(GridRegion destination, UUID userID, UUID itemID);
98 103
99 #endregion Objects 104 #endregion Objects
100 105
101 #region Regions
102
103 bool HelloNeighbour(ulong regionHandle, RegionInfo thisRegion);
104
105 #endregion Regions
106
107 } 106 }
108} 107}
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..4d7103b 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,7 +381,7 @@ 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
@@ -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..dc5ca51
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -0,0 +1,977 @@
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, string message,
226 GridRegion home, IPEndPoint clientIP)
227 : this()
228 {
229 FillOutInventoryData(invSkel, libService);
230
231 CircuitCode = (int)aCircuit.circuitcode;
232 Lastname = account.LastName;
233 Firstname = account.FirstName;
234 AgentID = account.PrincipalID;
235 SessionID = aCircuit.SessionID;
236 SecureSessionID = aCircuit.SecureSessionID;
237 Message = message;
238 BuddList = ConvertFriendListItem(friendsList);
239 StartLocation = where;
240
241 FillOutHomeData(pinfo, home);
242 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
243
244 FillOutRegionData(destination);
245
246 FillOutSeedCap(aCircuit, destination, clientIP);
247
248 }
249
250 private void FillOutInventoryData(List<InventoryFolderBase> invSkel, ILibraryService libService)
251 {
252 InventoryData inventData = null;
253
254 try
255 {
256 inventData = GetInventorySkeleton(invSkel);
257 }
258 catch (Exception e)
259 {
260 m_log.WarnFormat(
261 "[LLLOGIN SERVICE]: Error processing inventory skeleton of agent {0} - {1}",
262 agentID, e);
263
264 // ignore and continue
265 }
266
267 if (inventData != null)
268 {
269 ArrayList AgentInventoryArray = inventData.InventoryArray;
270
271 Hashtable InventoryRootHash = new Hashtable();
272 InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
273 InventoryRoot = new ArrayList();
274 InventoryRoot.Add(InventoryRootHash);
275 InventorySkeleton = AgentInventoryArray;
276 }
277
278 // Inventory Library Section
279 if (libService != null && libService.LibraryRootFolder != null)
280 {
281 Hashtable InventoryLibRootHash = new Hashtable();
282 InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
283 InventoryLibRoot = new ArrayList();
284 InventoryLibRoot.Add(InventoryLibRootHash);
285
286 InventoryLibraryOwner = GetLibraryOwner(libService.LibraryRootFolder);
287 InventoryLibrary = GetInventoryLibrary(libService);
288 }
289 }
290
291 private void FillOutHomeData(GridUserInfo pinfo, GridRegion home)
292 {
293 int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize;
294 if (home != null)
295 {
296 x = home.RegionLocX;
297 y = home.RegionLocY;
298 }
299
300 Home = string.Format(
301 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
302 x,
303 y,
304 pinfo.HomePosition.X, pinfo.HomePosition.Y, pinfo.HomePosition.Z,
305 pinfo.HomeLookAt.X, pinfo.HomeLookAt.Y, pinfo.HomeLookAt.Z);
306
307 }
308
309 private void FillOutRegionData(GridRegion destination)
310 {
311 IPEndPoint endPoint = destination.ExternalEndPoint;
312 SimAddress = endPoint.Address.ToString();
313 SimPort = (uint)endPoint.Port;
314 RegionX = (uint)destination.RegionLocX;
315 RegionY = (uint)destination.RegionLocY;
316 }
317
318 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient)
319 {
320 string capsSeedPath = String.Empty;
321
322 // Don't use the following! It Fails for logging into any region not on the same port as the http server!
323 // Kept here so it doesn't happen again!
324 // response.SeedCapability = regionInfo.ServerURI + capsSeedPath;
325
326 #region IP Translation for NAT
327 if (ipepClient != null)
328 {
329 capsSeedPath
330 = "http://"
331 + NetworkUtil.GetHostFor(ipepClient.Address, destination.ExternalHostName)
332 + ":"
333 + destination.HttpPort
334 + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
335 }
336 else
337 {
338 capsSeedPath
339 = "http://"
340 + destination.ExternalHostName
341 + ":"
342 + destination.HttpPort
343 + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
344 }
345 #endregion
346
347 SeedCapability = capsSeedPath;
348 }
349
350 private void SetDefaultValues()
351 {
352 DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
353 StipendSinceLogin = "N";
354 Gendered = "Y";
355 EverLoggedIn = "Y";
356 login = "false";
357 firstname = "Test";
358 lastname = "User";
359 agentAccess = "M";
360 agentAccessMax = "A";
361 startLocation = "last";
362 allowFirstLife = "Y";
363
364 ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock.";
365 ErrorReason = "key";
366 welcomeMessage = "Welcome to OpenSim!";
367 seedCapability = String.Empty;
368 home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" +
369 userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" +
370 userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" +
371 userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}";
372 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
373 RegionX = (uint) 255232;
374 RegionY = (uint) 254976;
375
376 // Classifieds;
377 AddClassifiedCategory((Int32) 1, "Shopping");
378 AddClassifiedCategory((Int32) 2, "Land Rental");
379 AddClassifiedCategory((Int32) 3, "Property Rental");
380 AddClassifiedCategory((Int32) 4, "Special Attraction");
381 AddClassifiedCategory((Int32) 5, "New Products");
382 AddClassifiedCategory((Int32) 6, "Employment");
383 AddClassifiedCategory((Int32) 7, "Wanted");
384 AddClassifiedCategory((Int32) 8, "Service");
385 AddClassifiedCategory((Int32) 9, "Personal");
386
387 SessionID = UUID.Random();
388 SecureSessionID = UUID.Random();
389 AgentID = UUID.Random();
390
391 Hashtable InitialOutfitHash = new Hashtable();
392 InitialOutfitHash["folder_name"] = "Nightclub Female";
393 InitialOutfitHash["gender"] = "female";
394 initialOutfit.Add(InitialOutfitHash);
395 }
396
397
398 public override Hashtable ToHashtable()
399 {
400 try
401 {
402 Hashtable responseData = new Hashtable();
403
404 loginFlagsHash = new Hashtable();
405 loginFlagsHash["daylight_savings"] = DST;
406 loginFlagsHash["stipend_since_login"] = StipendSinceLogin;
407 loginFlagsHash["gendered"] = Gendered;
408 loginFlagsHash["ever_logged_in"] = EverLoggedIn;
409 loginFlags.Add(loginFlagsHash);
410
411 responseData["first_name"] = Firstname;
412 responseData["last_name"] = Lastname;
413 responseData["agent_access"] = agentAccess;
414 responseData["agent_access_max"] = agentAccessMax;
415
416 globalTextures.Add(globalTexturesHash);
417 // this.eventCategories.Add(this.eventCategoriesHash);
418
419 AddToUIConfig("allow_first_life", allowFirstLife);
420 uiConfig.Add(uiConfigHash);
421
422 responseData["sim_port"] = (Int32) SimPort;
423 responseData["sim_ip"] = SimAddress;
424 responseData["http_port"] = (Int32)SimHttpPort;
425
426 responseData["agent_id"] = AgentID.ToString();
427 responseData["session_id"] = SessionID.ToString();
428 responseData["secure_session_id"] = SecureSessionID.ToString();
429 responseData["circuit_code"] = CircuitCode;
430 responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
431 responseData["login-flags"] = loginFlags;
432 responseData["global-textures"] = globalTextures;
433 responseData["seed_capability"] = seedCapability;
434
435 responseData["event_categories"] = eventCategories;
436 responseData["event_notifications"] = new ArrayList(); // todo
437 responseData["classified_categories"] = classifiedCategories;
438 responseData["ui-config"] = uiConfig;
439
440 if (agentInventory != null)
441 {
442 responseData["inventory-skeleton"] = agentInventory;
443 responseData["inventory-root"] = inventoryRoot;
444 }
445 responseData["inventory-skel-lib"] = inventoryLibrary;
446 responseData["inventory-lib-root"] = inventoryLibRoot;
447 responseData["gestures"] = activeGestures;
448 responseData["inventory-lib-owner"] = inventoryLibraryOwner;
449 responseData["initial-outfit"] = initialOutfit;
450 responseData["start_location"] = startLocation;
451 responseData["seed_capability"] = seedCapability;
452 responseData["home"] = home;
453 responseData["look_at"] = lookAt;
454 responseData["message"] = welcomeMessage;
455 responseData["region_x"] = (Int32)(RegionX);
456 responseData["region_y"] = (Int32)(RegionY);
457
458 if (m_buddyList != null)
459 {
460 responseData["buddy-list"] = m_buddyList.ToArray();
461 }
462
463 responseData["login"] = "true";
464
465 return responseData;
466 }
467 catch (Exception e)
468 {
469 m_log.Warn("[CLIENT]: LoginResponse: Error creating Hashtable Response: " + e.Message);
470
471 return LLFailedLoginResponse.InternalError.ToHashtable();
472 }
473 }
474
475 public override OSD ToOSDMap()
476 {
477 try
478 {
479 OSDMap map = new OSDMap();
480
481 map["first_name"] = OSD.FromString(Firstname);
482 map["last_name"] = OSD.FromString(Lastname);
483 map["agent_access"] = OSD.FromString(agentAccess);
484 map["agent_access_max"] = OSD.FromString(agentAccessMax);
485
486 map["sim_port"] = OSD.FromInteger(SimPort);
487 map["sim_ip"] = OSD.FromString(SimAddress);
488
489 map["agent_id"] = OSD.FromUUID(AgentID);
490 map["session_id"] = OSD.FromUUID(SessionID);
491 map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
492 map["circuit_code"] = OSD.FromInteger(CircuitCode);
493 map["seconds_since_epoch"] = OSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
494
495 #region Login Flags
496
497 OSDMap loginFlagsLLSD = new OSDMap();
498 loginFlagsLLSD["daylight_savings"] = OSD.FromString(DST);
499 loginFlagsLLSD["stipend_since_login"] = OSD.FromString(StipendSinceLogin);
500 loginFlagsLLSD["gendered"] = OSD.FromString(Gendered);
501 loginFlagsLLSD["ever_logged_in"] = OSD.FromString(EverLoggedIn);
502 map["login-flags"] = WrapOSDMap(loginFlagsLLSD);
503
504 #endregion Login Flags
505
506 #region Global Textures
507
508 OSDMap globalTexturesLLSD = new OSDMap();
509 globalTexturesLLSD["sun_texture_id"] = OSD.FromString(SunTexture);
510 globalTexturesLLSD["cloud_texture_id"] = OSD.FromString(CloudTexture);
511 globalTexturesLLSD["moon_texture_id"] = OSD.FromString(MoonTexture);
512
513 map["global-textures"] = WrapOSDMap(globalTexturesLLSD);
514
515 #endregion Global Textures
516
517 map["seed_capability"] = OSD.FromString(seedCapability);
518
519 map["event_categories"] = ArrayListToOSDArray(eventCategories);
520 //map["event_notifications"] = new OSDArray(); // todo
521 map["classified_categories"] = ArrayListToOSDArray(classifiedCategories);
522
523 #region UI Config
524
525 OSDMap uiConfigLLSD = new OSDMap();
526 uiConfigLLSD["allow_first_life"] = OSD.FromString(allowFirstLife);
527 map["ui-config"] = WrapOSDMap(uiConfigLLSD);
528
529 #endregion UI Config
530
531 #region Inventory
532
533 map["inventory-skeleton"] = ArrayListToOSDArray(agentInventory);
534
535 map["inventory-skel-lib"] = ArrayListToOSDArray(inventoryLibrary);
536 map["inventory-root"] = ArrayListToOSDArray(inventoryRoot); ;
537 map["inventory-lib-root"] = ArrayListToOSDArray(inventoryLibRoot);
538 map["inventory-lib-owner"] = ArrayListToOSDArray(inventoryLibraryOwner);
539
540 #endregion Inventory
541
542 map["gestures"] = ArrayListToOSDArray(activeGestures);
543
544 map["initial-outfit"] = ArrayListToOSDArray(initialOutfit);
545 map["start_location"] = OSD.FromString(startLocation);
546
547 map["seed_capability"] = OSD.FromString(seedCapability);
548 map["home"] = OSD.FromString(home);
549 map["look_at"] = OSD.FromString(lookAt);
550 map["message"] = OSD.FromString(welcomeMessage);
551 map["region_x"] = OSD.FromInteger(RegionX);
552 map["region_y"] = OSD.FromInteger(RegionY);
553
554 if (m_buddyList != null)
555 {
556 map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray());
557 }
558
559 map["login"] = OSD.FromString("true");
560
561 return map;
562 }
563 catch (Exception e)
564 {
565 m_log.Warn("[CLIENT]: LoginResponse: Error creating LLSD Response: " + e.Message);
566
567 return LLFailedLoginResponse.InternalError.ToOSDMap();
568 }
569 }
570
571 public OSDArray ArrayListToOSDArray(ArrayList arrlst)
572 {
573 OSDArray llsdBack = new OSDArray();
574 foreach (Hashtable ht in arrlst)
575 {
576 OSDMap mp = new OSDMap();
577 foreach (DictionaryEntry deHt in ht)
578 {
579 mp.Add((string)deHt.Key, OSDString.FromObject(deHt.Value));
580 }
581 llsdBack.Add(mp);
582 }
583 return llsdBack;
584 }
585
586 private static OSDArray WrapOSDMap(OSDMap wrapMe)
587 {
588 OSDArray array = new OSDArray();
589 array.Add(wrapMe);
590 return array;
591 }
592
593 public void SetEventCategories(string category, string value)
594 {
595 // this.eventCategoriesHash[category] = value;
596 //TODO
597 }
598
599 public void AddToUIConfig(string itemName, string item)
600 {
601 uiConfigHash[itemName] = item;
602 }
603
604 public void AddClassifiedCategory(Int32 ID, string categoryName)
605 {
606 Hashtable hash = new Hashtable();
607 hash["category_name"] = categoryName;
608 hash["category_id"] = ID;
609 classifiedCategories.Add(hash);
610 // this.classifiedCategoriesHash.Clear();
611 }
612
613
614 private static LLLoginResponse.BuddyList ConvertFriendListItem(FriendInfo[] friendsList)
615 {
616 LLLoginResponse.BuddyList buddylistreturn = new LLLoginResponse.BuddyList();
617 foreach (FriendInfo finfo in friendsList)
618 {
619 if (finfo.TheirFlags == -1)
620 continue;
621 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
622 buddyitem.BuddyID = finfo.Friend;
623 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
624 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
625 buddylistreturn.AddNewBuddy(buddyitem);
626 }
627 return buddylistreturn;
628 }
629
630 private InventoryData GetInventorySkeleton(List<InventoryFolderBase> folders)
631 {
632 UUID rootID = UUID.Zero;
633 ArrayList AgentInventoryArray = new ArrayList();
634 Hashtable TempHash;
635 foreach (InventoryFolderBase InvFolder in folders)
636 {
637 if (InvFolder.ParentID == UUID.Zero)
638 {
639 rootID = InvFolder.ID;
640 }
641 TempHash = new Hashtable();
642 TempHash["name"] = InvFolder.Name;
643 TempHash["parent_id"] = InvFolder.ParentID.ToString();
644 TempHash["version"] = (Int32)InvFolder.Version;
645 TempHash["type_default"] = (Int32)InvFolder.Type;
646 TempHash["folder_id"] = InvFolder.ID.ToString();
647 AgentInventoryArray.Add(TempHash);
648 }
649
650 return new InventoryData(AgentInventoryArray, rootID);
651
652 }
653
654 /// <summary>
655 /// Converts the inventory library skeleton into the form required by the rpc request.
656 /// </summary>
657 /// <returns></returns>
658 protected virtual ArrayList GetInventoryLibrary(ILibraryService library)
659 {
660 Dictionary<UUID, InventoryFolderImpl> rootFolders = library.GetAllFolders();
661 m_log.DebugFormat("[LLOGIN]: Library has {0} folders", rootFolders.Count);
662 //Dictionary<UUID, InventoryFolderImpl> rootFolders = new Dictionary<UUID,InventoryFolderImpl>();
663 ArrayList folderHashes = new ArrayList();
664
665 foreach (InventoryFolderBase folder in rootFolders.Values)
666 {
667 Hashtable TempHash = new Hashtable();
668 TempHash["name"] = folder.Name;
669 TempHash["parent_id"] = folder.ParentID.ToString();
670 TempHash["version"] = (Int32)folder.Version;
671 TempHash["type_default"] = (Int32)folder.Type;
672 TempHash["folder_id"] = folder.ID.ToString();
673 folderHashes.Add(TempHash);
674 }
675
676 return folderHashes;
677 }
678
679 /// <summary>
680 ///
681 /// </summary>
682 /// <returns></returns>
683 protected virtual ArrayList GetLibraryOwner(InventoryFolderImpl libFolder)
684 {
685 //for now create random inventory library owner
686 Hashtable TempHash = new Hashtable();
687 TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000"; // libFolder.Owner
688 ArrayList inventoryLibOwner = new ArrayList();
689 inventoryLibOwner.Add(TempHash);
690 return inventoryLibOwner;
691 }
692
693 public class InventoryData
694 {
695 public ArrayList InventoryArray = null;
696 public UUID RootFolderID = UUID.Zero;
697
698 public InventoryData(ArrayList invList, UUID rootID)
699 {
700 InventoryArray = invList;
701 RootFolderID = rootID;
702 }
703 }
704
705 #region Properties
706
707 public string Login
708 {
709 get { return login; }
710 set { login = value; }
711 }
712
713 public string DST
714 {
715 get { return dst; }
716 set { dst = value; }
717 }
718
719 public string StipendSinceLogin
720 {
721 get { return stipendSinceLogin; }
722 set { stipendSinceLogin = value; }
723 }
724
725 public string Gendered
726 {
727 get { return gendered; }
728 set { gendered = value; }
729 }
730
731 public string EverLoggedIn
732 {
733 get { return everLoggedIn; }
734 set { everLoggedIn = value; }
735 }
736
737 public uint SimPort
738 {
739 get { return simPort; }
740 set { simPort = value; }
741 }
742
743 public uint SimHttpPort
744 {
745 get { return simHttpPort; }
746 set { simHttpPort = value; }
747 }
748
749 public string SimAddress
750 {
751 get { return simAddress; }
752 set { simAddress = value; }
753 }
754
755 public UUID AgentID
756 {
757 get { return agentID; }
758 set { agentID = value; }
759 }
760
761 public UUID SessionID
762 {
763 get { return sessionID; }
764 set { sessionID = value; }
765 }
766
767 public UUID SecureSessionID
768 {
769 get { return secureSessionID; }
770 set { secureSessionID = value; }
771 }
772
773 public Int32 CircuitCode
774 {
775 get { return circuitCode; }
776 set { circuitCode = value; }
777 }
778
779 public uint RegionX
780 {
781 get { return regionX; }
782 set { regionX = value; }
783 }
784
785 public uint RegionY
786 {
787 get { return regionY; }
788 set { regionY = value; }
789 }
790
791 public string SunTexture
792 {
793 get { return sunTexture; }
794 set { sunTexture = value; }
795 }
796
797 public string CloudTexture
798 {
799 get { return cloudTexture; }
800 set { cloudTexture = value; }
801 }
802
803 public string MoonTexture
804 {
805 get { return moonTexture; }
806 set { moonTexture = value; }
807 }
808
809 public string Firstname
810 {
811 get { return firstname; }
812 set { firstname = value; }
813 }
814
815 public string Lastname
816 {
817 get { return lastname; }
818 set { lastname = value; }
819 }
820
821 public string AgentAccess
822 {
823 get { return agentAccess; }
824 set { agentAccess = value; }
825 }
826
827 public string AgentAccessMax
828 {
829 get { return agentAccessMax; }
830 set { agentAccessMax = value; }
831 }
832
833 public string StartLocation
834 {
835 get { return startLocation; }
836 set { startLocation = value; }
837 }
838
839 public string LookAt
840 {
841 get { return lookAt; }
842 set { lookAt = value; }
843 }
844
845 public string SeedCapability
846 {
847 get { return seedCapability; }
848 set { seedCapability = value; }
849 }
850
851 public string ErrorReason
852 {
853 get { return errorReason; }
854 set { errorReason = value; }
855 }
856
857 public string ErrorMessage
858 {
859 get { return errorMessage; }
860 set { errorMessage = value; }
861 }
862
863 public ArrayList InventoryRoot
864 {
865 get { return inventoryRoot; }
866 set { inventoryRoot = value; }
867 }
868
869 public ArrayList InventorySkeleton
870 {
871 get { return agentInventory; }
872 set { agentInventory = value; }
873 }
874
875 public ArrayList InventoryLibrary
876 {
877 get { return inventoryLibrary; }
878 set { inventoryLibrary = value; }
879 }
880
881 public ArrayList InventoryLibraryOwner
882 {
883 get { return inventoryLibraryOwner; }
884 set { inventoryLibraryOwner = value; }
885 }
886
887 public ArrayList InventoryLibRoot
888 {
889 get { return inventoryLibRoot; }
890 set { inventoryLibRoot = value; }
891 }
892
893 public ArrayList ActiveGestures
894 {
895 get { return activeGestures; }
896 set { activeGestures = value; }
897 }
898
899 public string Home
900 {
901 get { return home; }
902 set { home = value; }
903 }
904
905 public string Message
906 {
907 get { return welcomeMessage; }
908 set { welcomeMessage = value; }
909 }
910
911 public BuddyList BuddList
912 {
913 get { return m_buddyList; }
914 set { m_buddyList = value; }
915 }
916
917 #endregion
918
919 public class UserInfo
920 {
921 public string firstname;
922 public string lastname;
923 public ulong homeregionhandle;
924 public Vector3 homepos;
925 public Vector3 homelookat;
926 }
927
928 public class BuddyList
929 {
930 public List<BuddyInfo> Buddies = new List<BuddyInfo>();
931
932 public void AddNewBuddy(BuddyInfo buddy)
933 {
934 if (!Buddies.Contains(buddy))
935 {
936 Buddies.Add(buddy);
937 }
938 }
939
940 public ArrayList ToArray()
941 {
942 ArrayList buddyArray = new ArrayList();
943 foreach (BuddyInfo buddy in Buddies)
944 {
945 buddyArray.Add(buddy.ToHashTable());
946 }
947 return buddyArray;
948 }
949
950 public class BuddyInfo
951 {
952 public int BuddyRightsHave = 1;
953 public int BuddyRightsGiven = 1;
954 public string BuddyID;
955
956 public BuddyInfo(string buddyID)
957 {
958 BuddyID = buddyID;
959 }
960
961 public BuddyInfo(UUID buddyID)
962 {
963 BuddyID = buddyID.ToString();
964 }
965
966 public Hashtable ToHashTable()
967 {
968 Hashtable hTable = new Hashtable();
969 hTable["buddy_rights_has"] = BuddyRightsHave;
970 hTable["buddy_rights_given"] = BuddyRightsGiven;
971 hTable["buddy_id"] = BuddyID;
972 return hTable;
973 }
974 }
975 }
976 }
977}
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
new file mode 100644
index 0000000..398fe4f
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -0,0 +1,801 @@
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 private ISimulationService m_LocalSimulationService;
62 private ISimulationService m_RemoteSimulationService;
63 protected ILibraryService m_LibraryService;
64 protected IFriendsService m_FriendsService;
65 protected IAvatarService m_AvatarService;
66 private IUserAgentService m_UserAgentService;
67
68 private GatekeeperServiceConnector m_GatekeeperConnector;
69
70 private string m_DefaultRegionName;
71 protected string m_WelcomeMessage;
72 private bool m_RequireInventory;
73 protected int m_MinLoginLevel;
74 private string m_GatekeeperURL;
75 private 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 //
282 // Login the presence
283 //
284 if (m_PresenceService != null)
285 {
286 success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession);
287 if (!success)
288 {
289 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: could not login presence");
290 return LLFailedLoginResponse.GridProblem;
291 }
292 }
293
294 //
295 // Change Online status and get the home region
296 //
297 GridRegion home = null;
298 GridUserInfo guinfo = m_GridUserService.LoggedIn(account.PrincipalID.ToString());
299 if (guinfo != null && (guinfo.HomeRegionID != UUID.Zero) && m_GridService != null)
300 {
301 home = m_GridService.GetRegionByUUID(scopeID, guinfo.HomeRegionID);
302 }
303 if (guinfo == null)
304 {
305 // something went wrong, make something up, so that we don't have to test this anywhere else
306 guinfo = new GridUserInfo();
307 guinfo.LastPosition = guinfo.HomePosition = new Vector3(128, 128, 30);
308 }
309
310 //
311 // Find the destination region/grid
312 //
313 string where = string.Empty;
314 Vector3 position = Vector3.Zero;
315 Vector3 lookAt = Vector3.Zero;
316 GridRegion gatekeeper = null;
317 GridRegion destination = FindDestination(account, scopeID, guinfo, session, startLocation, home, out gatekeeper, out where, out position, out lookAt);
318 if (destination == null)
319 {
320 m_PresenceService.LogoutAgent(session);
321 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
322 return LLFailedLoginResponse.GridProblem;
323 }
324
325 //
326 // Get the avatar
327 //
328 AvatarData avatar = null;
329 if (m_AvatarService != null)
330 {
331 avatar = m_AvatarService.GetAvatar(account.PrincipalID);
332 }
333
334 //
335 // Instantiate/get the simulation interface and launch an agent at the destination
336 //
337 string reason = string.Empty;
338 AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, out where, out reason);
339
340 if (aCircuit == null)
341 {
342 m_PresenceService.LogoutAgent(session);
343 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason);
344 return LLFailedLoginResponse.AuthorizationProblem;
345
346 }
347 // Get Friends list
348 FriendInfo[] friendsList = new FriendInfo[0];
349 if (m_FriendsService != null)
350 {
351 friendsList = m_FriendsService.GetFriends(account.PrincipalID);
352 m_log.DebugFormat("[LLOGIN SERVICE]: Retrieved {0} friends", friendsList.Length);
353 }
354
355 //
356 // Finally, fill out the response and return it
357 //
358 LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
359 where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP);
360
361 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
362 return response;
363 }
364 catch (Exception e)
365 {
366 m_log.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2} {3}", firstName, lastName, e.ToString(), e.StackTrace);
367 if (m_PresenceService != null)
368 m_PresenceService.LogoutAgent(session);
369 return LLFailedLoginResponse.InternalError;
370 }
371 }
372
373 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)
374 {
375 m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation);
376
377 gatekeeper = null;
378 where = "home";
379 position = new Vector3(128, 128, 0);
380 lookAt = new Vector3(0, 1, 0);
381
382 if (m_GridService == null)
383 return null;
384
385 if (startLocation.Equals("home"))
386 {
387 // logging into home region
388 if (pinfo == null)
389 return null;
390
391 GridRegion region = null;
392
393 bool tryDefaults = false;
394
395 if (home == null)
396 {
397 m_log.WarnFormat(
398 "[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set",
399 account.FirstName, account.LastName);
400
401 tryDefaults = true;
402 }
403 else
404 {
405 region = home;
406
407 position = pinfo.HomePosition;
408 lookAt = pinfo.HomeLookAt;
409 }
410
411 if (tryDefaults)
412 {
413 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
414 if (defaults != null && defaults.Count > 0)
415 {
416 region = defaults[0];
417 where = "safe";
418 }
419 else
420 {
421 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",
422 account.FirstName, account.LastName);
423 defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
424 if (defaults != null && defaults.Count > 0)
425 {
426 region = defaults[0];
427 where = "safe";
428 }
429 }
430 }
431
432 return region;
433 }
434 else if (startLocation.Equals("last"))
435 {
436 // logging into last visited region
437 where = "last";
438
439 if (pinfo == null)
440 return null;
441
442 GridRegion region = null;
443
444 if (pinfo.LastRegionID.Equals(UUID.Zero) || (region = m_GridService.GetRegionByUUID(scopeID, pinfo.LastRegionID)) == null)
445 {
446 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
447 if (defaults != null && defaults.Count > 0)
448 {
449 region = defaults[0];
450 where = "safe";
451 }
452 else
453 {
454 m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
455 defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
456 if (defaults != null && defaults.Count > 0)
457 {
458 region = defaults[0];
459 where = "safe";
460 }
461 }
462
463 }
464 else
465 {
466 position = pinfo.LastPosition;
467 lookAt = pinfo.LastLookAt;
468 }
469
470 return region;
471 }
472 else
473 {
474 // free uri form
475 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
476 where = "url";
477 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
478 Match uriMatch = reURI.Match(startLocation);
479 if (uriMatch == null)
480 {
481 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, but can't process it", startLocation);
482 return null;
483 }
484 else
485 {
486 position = new Vector3(float.Parse(uriMatch.Groups["x"].Value, Culture.NumberFormatInfo),
487 float.Parse(uriMatch.Groups["y"].Value, Culture.NumberFormatInfo),
488 float.Parse(uriMatch.Groups["z"].Value, Culture.NumberFormatInfo));
489
490 string regionName = uriMatch.Groups["region"].ToString();
491 if (regionName != null)
492 {
493 if (!regionName.Contains("@"))
494 {
495 List<GridRegion> regions = m_GridService.GetRegionsByName(scopeID, regionName, 1);
496 if ((regions == null) || (regions != null && regions.Count == 0))
497 {
498 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}. Trying defaults.", startLocation, regionName);
499 regions = m_GridService.GetDefaultRegions(scopeID);
500 if (regions != null && regions.Count > 0)
501 {
502 where = "safe";
503 return regions[0];
504 }
505 else
506 {
507 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation);
508 return null;
509 }
510 }
511 return regions[0];
512 }
513 else
514 {
515 if (m_UserAgentService == null)
516 {
517 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");
518 return null;
519 }
520 string[] parts = regionName.Split(new char[] { '@' });
521 if (parts.Length < 2)
522 {
523 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName);
524 return null;
525 }
526 // Valid specification of a remote grid
527
528 regionName = parts[0];
529 string domainLocator = parts[1];
530 parts = domainLocator.Split(new char[] {':'});
531 string domainName = parts[0];
532 uint port = 0;
533 if (parts.Length > 1)
534 UInt32.TryParse(parts[1], out port);
535
536 GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
537 return region;
538 }
539 }
540 else
541 {
542 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
543 if (defaults != null && defaults.Count > 0)
544 {
545 where = "safe";
546 return defaults[0];
547 }
548 else
549 return null;
550 }
551 }
552 //response.LookAt = "[r0,r1,r0]";
553 //// can be: last, home, safe, url
554 //response.StartLocation = "url";
555
556 }
557
558 }
559
560 private GridRegion FindForeignRegion(string domainName, uint port, string regionName, out GridRegion gatekeeper)
561 {
562 gatekeeper = new GridRegion();
563 gatekeeper.ExternalHostName = domainName;
564 gatekeeper.HttpPort = port;
565 gatekeeper.RegionName = regionName;
566 gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
567
568 UUID regionID;
569 ulong handle;
570 string imageURL = string.Empty, reason = string.Empty;
571 if (m_GatekeeperConnector.LinkRegion(gatekeeper, out regionID, out handle, out domainName, out imageURL, out reason))
572 {
573 GridRegion destination = m_GatekeeperConnector.GetHyperlinkRegion(gatekeeper, regionID);
574 return destination;
575 }
576
577 return null;
578 }
579
580 private string hostName = string.Empty;
581 private int port = 0;
582
583 private void SetHostAndPort(string url)
584 {
585 try
586 {
587 Uri uri = new Uri(url);
588 hostName = uri.Host;
589 port = uri.Port;
590 }
591 catch
592 {
593 m_log.WarnFormat("[LLLogin SERVICE]: Unable to parse GatekeeperURL {0}", url);
594 }
595 }
596
597 protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar,
598 UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, out string where, out string reason)
599 {
600 where = currentWhere;
601 ISimulationService simConnector = null;
602 reason = string.Empty;
603 uint circuitCode = 0;
604 AgentCircuitData aCircuit = null;
605
606 if (m_UserAgentService == null)
607 {
608 // HG standalones have both a localSimulatonDll and a remoteSimulationDll
609 // non-HG standalones have just a localSimulationDll
610 // independent login servers have just a remoteSimulationDll
611 if (m_LocalSimulationService != null)
612 simConnector = m_LocalSimulationService;
613 else if (m_RemoteSimulationService != null)
614 simConnector = m_RemoteSimulationService;
615 }
616 else // User Agent Service is on
617 {
618 if (gatekeeper == null) // login to local grid
619 {
620 if (hostName == string.Empty)
621 SetHostAndPort(m_GatekeeperURL);
622
623 gatekeeper = new GridRegion(destination);
624 gatekeeper.ExternalHostName = hostName;
625 gatekeeper.HttpPort = (uint)port;
626
627 }
628 else // login to foreign grid
629 {
630 }
631 }
632
633 bool success = false;
634
635 if (m_UserAgentService == null && simConnector != null)
636 {
637 circuitCode = (uint)Util.RandomClass.Next(); ;
638 aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer);
639 success = LaunchAgentDirectly(simConnector, destination, aCircuit, out reason);
640 if (!success && m_GridService != null)
641 {
642 // Try the fallback regions
643 List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
644 if (fallbacks != null)
645 {
646 foreach (GridRegion r in fallbacks)
647 {
648 success = LaunchAgentDirectly(simConnector, r, aCircuit, out reason);
649 if (success)
650 {
651 where = "safe";
652 destination = r;
653 break;
654 }
655 }
656 }
657 }
658 }
659
660 if (m_UserAgentService != null)
661 {
662 circuitCode = (uint)Util.RandomClass.Next(); ;
663 aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer);
664 success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, out reason);
665 if (!success && m_GridService != null)
666 {
667 // Try the fallback regions
668 List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
669 if (fallbacks != null)
670 {
671 foreach (GridRegion r in fallbacks)
672 {
673 success = LaunchAgentIndirectly(gatekeeper, r, aCircuit, out reason);
674 if (success)
675 {
676 where = "safe";
677 destination = r;
678 break;
679 }
680 }
681 }
682 }
683 }
684
685 if (success)
686 return aCircuit;
687 else
688 return null;
689 }
690
691 private AgentCircuitData MakeAgent(GridRegion region, UserAccount account,
692 AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position, string viewer)
693 {
694 AgentCircuitData aCircuit = new AgentCircuitData();
695
696 aCircuit.AgentID = account.PrincipalID;
697 if (avatar != null)
698 aCircuit.Appearance = avatar.ToAvatarAppearance(account.PrincipalID);
699 else
700 aCircuit.Appearance = new AvatarAppearance(account.PrincipalID);
701
702 //aCircuit.BaseFolder = irrelevant
703 aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
704 aCircuit.child = false; // the first login agent is root
705 aCircuit.ChildrenCapSeeds = new Dictionary<ulong, string>();
706 aCircuit.circuitcode = circuit;
707 aCircuit.firstname = account.FirstName;
708 //aCircuit.InventoryFolder = irrelevant
709 aCircuit.lastname = account.LastName;
710 aCircuit.SecureSessionID = secureSession;
711 aCircuit.SessionID = session;
712 aCircuit.startpos = position;
713 aCircuit.Viewer = viewer;
714 SetServiceURLs(aCircuit, account);
715
716 return aCircuit;
717
718 //m_UserAgentService.LoginAgentToGrid(aCircuit, GatekeeperServiceConnector, region, out reason);
719 //if (simConnector.CreateAgent(region, aCircuit, 0, out reason))
720 // return aCircuit;
721
722 //return null;
723
724 }
725
726 private void SetServiceURLs(AgentCircuitData aCircuit, UserAccount account)
727 {
728 aCircuit.ServiceURLs = new Dictionary<string, object>();
729 if (account.ServiceURLs == null)
730 return;
731
732 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs)
733 {
734 if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty))
735 {
736 aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty);
737 }
738 else
739 {
740 aCircuit.ServiceURLs[kvp.Key] = kvp.Value;
741 }
742 }
743 }
744
745 private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, out string reason)
746 {
747 return simConnector.CreateAgent(region, aCircuit, (int)Constants.TeleportFlags.ViaLogin, out reason);
748 }
749
750 private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, out string reason)
751 {
752 m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
753 return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason);
754 }
755
756 #region Console Commands
757 private void RegisterCommands()
758 {
759 //MainConsole.Instance.Commands.AddCommand
760 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login level",
761 "login level <level>",
762 "Set the minimum user level to log in", HandleLoginCommand);
763
764 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login reset",
765 "login reset",
766 "Reset the login level to allow all users",
767 HandleLoginCommand);
768
769 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login text",
770 "login text <text>",
771 "Set the text users will see on login", HandleLoginCommand);
772
773 }
774
775 private void HandleLoginCommand(string module, string[] cmd)
776 {
777 string subcommand = cmd[1];
778
779 switch (subcommand)
780 {
781 case "level":
782 // Set the minimum level to allow login
783 // Useful to allow grid update without worrying about users.
784 // or fixing critical issues
785 //
786 if (cmd.Length > 2)
787 Int32.TryParse(cmd[2], out m_MinLoginLevel);
788 break;
789 case "reset":
790 m_MinLoginLevel = 0;
791 break;
792 case "text":
793 if (cmd.Length > 2)
794 m_WelcomeMessage = cmd[2];
795 break;
796 }
797 }
798 }
799
800 #endregion
801}
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs
index 2157462..7e7e98e 100644
--- a/OpenSim/Services/PresenceService/PresenceService.cs
+++ b/OpenSim/Services/PresenceService/PresenceService.cs
@@ -41,27 +41,113 @@ 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 if (data.Data.ContainsKey("Position"))
119 ret.Position = Vector3.Parse(data.Data["Position"]);
120 if (data.Data.ContainsKey("LookAt"))
121 ret.LookAt = Vector3.Parse(data.Data["LookAt"]);
122
123 return ret;
124 }
125
126 public PresenceInfo[] GetAgents(string[] userIDs)
127 {
128 List<PresenceInfo> info = new List<PresenceInfo>();
129
130 foreach (string userIDStr in userIDs)
131 {
132 PresenceData[] data = m_Database.Get("UserID",
133 userIDStr);
134
135 foreach (PresenceData d in data)
136 {
137 PresenceInfo ret = new PresenceInfo();
138
139 ret.UserID = d.UserID;
140 ret.RegionID = d.RegionID;
141 ret.Position = Vector3.Parse(d.Data["Position"]);
142 ret.LookAt = Vector3.Parse(d.Data["LookAt"]);
143
144 info.Add(ret);
145 }
146 }
147
148 // m_log.DebugFormat("[PRESENCE SERVICE]: GetAgents for {0} userIDs found {1} presences", userIDs.Length, info.Count);
149 return info.ToArray();
150 }
151
66 } 152 }
67} 153}
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