aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services')
-rw-r--r--OpenSim/Services/Connectors/Inventory/HGInventoryServiceConnector.cs335
-rw-r--r--OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs140
-rw-r--r--OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs582
-rw-r--r--OpenSim/Services/Connectors/Inventory/QuickAndDirtyInventoryServiceConnector.cs196
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs262
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs55
-rw-r--r--OpenSim/Services/GridService/GridService.cs2
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs44
8 files changed, 324 insertions, 1292 deletions
diff --git a/OpenSim/Services/Connectors/Inventory/HGInventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/HGInventoryServiceConnector.cs
deleted file mode 100644
index 9878855..0000000
--- a/OpenSim/Services/Connectors/Inventory/HGInventoryServiceConnector.cs
+++ /dev/null
@@ -1,335 +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 Nini.Config;
30using System;
31using System.Collections.Generic;
32using System.Reflection;
33using OpenSim.Framework;
34using OpenSim.Services.Interfaces;
35using OpenMetaverse;
36
37namespace OpenSim.Services.Connectors.Inventory
38{
39 public class HGInventoryServiceConnector : ISessionAuthInventoryService
40 {
41 private static readonly ILog m_log =
42 LogManager.GetLogger(
43 MethodBase.GetCurrentMethod().DeclaringType);
44
45 private Dictionary<string, InventoryServicesConnector> m_connectors = new Dictionary<string, InventoryServicesConnector>();
46
47 public HGInventoryServiceConnector(IConfigSource source)
48 {
49 IConfig moduleConfig = source.Configs["Modules"];
50 if (moduleConfig != null)
51 {
52
53 IConfig inventoryConfig = source.Configs["InventoryService"];
54 if (inventoryConfig == null)
55 {
56 m_log.Error("[HG INVENTORY SERVICE]: InventoryService missing from OpenSim.ini");
57 return;
58 }
59
60 m_log.Info("[HG INVENTORY SERVICE]: HG inventory service enabled");
61 }
62 }
63
64 private bool StringToUrlAndUserID(string id, out string url, out string userID)
65 {
66 url = String.Empty;
67 userID = String.Empty;
68
69 Uri assetUri;
70
71 if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) &&
72 assetUri.Scheme == Uri.UriSchemeHttp)
73 {
74 url = "http://" + assetUri.Authority;
75 userID = assetUri.LocalPath.Trim(new char[] { '/' });
76 return true;
77 }
78
79 return false;
80 }
81 private ISessionAuthInventoryService GetConnector(string url)
82 {
83 InventoryServicesConnector connector = null;
84 lock (m_connectors)
85 {
86 if (m_connectors.ContainsKey(url))
87 {
88 connector = m_connectors[url];
89 }
90 else
91 {
92 // We're instantiating this class explicitly, but this won't
93 // work in general, because the remote grid may be running
94 // an inventory server that has a different protocol.
95 // Eventually we will want a piece of protocol asking
96 // the remote server about its kind. Definitely cool thing to do!
97 connector = new InventoryServicesConnector(url);
98 m_connectors.Add(url, connector);
99 }
100 }
101 return connector;
102 }
103
104 public string Host
105 {
106 get { return string.Empty; }
107 }
108
109 public void GetUserInventory(string id, UUID sessionID, InventoryReceiptCallback callback)
110 {
111 m_log.Debug("[HGInventory]: GetUserInventory " + id);
112 string url = string.Empty;
113 string userID = string.Empty;
114
115 if (StringToUrlAndUserID(id, out url, out userID))
116 {
117 ISessionAuthInventoryService connector = GetConnector(url);
118 connector.GetUserInventory(userID, sessionID, callback);
119 }
120
121 }
122
123 /// <summary>
124 /// Gets the user folder for the given folder-type
125 /// </summary>
126 /// <param name="userID"></param>
127 /// <param name="type"></param>
128 /// <returns></returns>
129 public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string id, UUID sessionID)
130 {
131 m_log.Debug("[HGInventory]: GetSystemFolders " + id);
132 string url = string.Empty;
133 string userID = string.Empty;
134
135 if (StringToUrlAndUserID(id, out url, out userID))
136 {
137 ISessionAuthInventoryService connector = GetConnector(url);
138 return connector.GetSystemFolders(userID, sessionID);
139 }
140
141 return new Dictionary<AssetType, InventoryFolderBase>();
142 }
143
144 /// <summary>
145 /// Gets everything (folders and items) inside a folder
146 /// </summary>
147 /// <param name="userId"></param>
148 /// <param name="folderID"></param>
149 /// <returns></returns>
150 public InventoryCollection GetFolderContent(string id, UUID folderID, UUID sessionID)
151 {
152 m_log.Debug("[HGInventory]: GetFolderContent " + id);
153 string url = string.Empty;
154 string userID = string.Empty;
155
156 if (StringToUrlAndUserID(id, out url, out userID))
157 {
158 ISessionAuthInventoryService connector = GetConnector(url);
159 return connector.GetFolderContent(userID, folderID, sessionID);
160 }
161
162 return null;
163 }
164
165 public bool AddFolder(string id, InventoryFolderBase folder, UUID sessionID)
166 {
167 string url = string.Empty;
168 string userID = string.Empty;
169
170 if (StringToUrlAndUserID(id, out url, out userID))
171 {
172 ISessionAuthInventoryService connector = GetConnector(url);
173 return connector.AddFolder(userID, folder, sessionID);
174 }
175 return false;
176 }
177
178 public bool UpdateFolder(string id, InventoryFolderBase folder, UUID sessionID)
179 {
180 string url = string.Empty;
181 string userID = string.Empty;
182
183 if (StringToUrlAndUserID(id, out url, out userID))
184 {
185 ISessionAuthInventoryService connector = GetConnector(url);
186 return connector.UpdateFolder(userID, folder, sessionID);
187 }
188 return false;
189 }
190
191 public bool MoveFolder(string id, InventoryFolderBase folder, UUID sessionID)
192 {
193 string url = string.Empty;
194 string userID = string.Empty;
195
196 if (StringToUrlAndUserID(id, out url, out userID))
197 {
198 ISessionAuthInventoryService connector = GetConnector(url);
199 return connector.MoveFolder(userID, folder, sessionID);
200 }
201 return false;
202 }
203
204 public bool DeleteFolders(string id, List<UUID> folders, UUID sessionID)
205 {
206 string url = string.Empty;
207 string userID = string.Empty;
208
209 if (StringToUrlAndUserID(id, out url, out userID))
210 {
211 ISessionAuthInventoryService connector = GetConnector(url);
212 return connector.DeleteFolders(userID, folders, sessionID);
213 }
214 return false;
215 }
216
217 public bool PurgeFolder(string id, InventoryFolderBase folder, UUID sessionID)
218 {
219 string url = string.Empty;
220 string userID = string.Empty;
221
222 if (StringToUrlAndUserID(id, out url, out userID))
223 {
224 ISessionAuthInventoryService connector = GetConnector(url);
225 return connector.PurgeFolder(userID, folder, sessionID);
226 }
227 return false;
228 }
229
230 public List<InventoryItemBase> GetFolderItems(string id, UUID folderID, UUID sessionID)
231 {
232 string url = string.Empty;
233 string userID = string.Empty;
234
235 if (StringToUrlAndUserID(id, out url, out userID))
236 {
237 ISessionAuthInventoryService connector = GetConnector(url);
238 return connector.GetFolderItems(userID, folderID, sessionID);
239 }
240 return new List<InventoryItemBase>();
241 }
242
243 public bool AddItem(string id, InventoryItemBase item, UUID sessionID)
244 {
245 string url = string.Empty;
246 string userID = string.Empty;
247
248 if (StringToUrlAndUserID(id, out url, out userID))
249 {
250 ISessionAuthInventoryService connector = GetConnector(url);
251 return connector.AddItem(userID, item, sessionID);
252 }
253 return false;
254 }
255
256 public bool UpdateItem(string id, InventoryItemBase item, UUID sessionID)
257 {
258 string url = string.Empty;
259 string userID = string.Empty;
260
261 if (StringToUrlAndUserID(id, out url, out userID))
262 {
263 ISessionAuthInventoryService connector = GetConnector(url);
264 return connector.UpdateItem(userID, item, sessionID);
265 }
266 return false;
267 }
268
269 public bool MoveItems(string id, List<InventoryItemBase> items, UUID sessionID)
270 {
271 string url = string.Empty;
272 string userID = string.Empty;
273
274 if (StringToUrlAndUserID(id, out url, out userID))
275 {
276 ISessionAuthInventoryService connector = GetConnector(url);
277 return connector.MoveItems(userID, items, sessionID);
278 }
279 return false;
280 }
281
282 public bool DeleteItems(string id, List<UUID> itemIDs, UUID sessionID)
283 {
284 string url = string.Empty;
285 string userID = string.Empty;
286
287 if (StringToUrlAndUserID(id, out url, out userID))
288 {
289 ISessionAuthInventoryService connector = GetConnector(url);
290 return connector.DeleteItems(userID, itemIDs, sessionID);
291 }
292 return false;
293 }
294
295 public InventoryItemBase QueryItem(string id, InventoryItemBase item, UUID sessionID)
296 {
297 string url = string.Empty;
298 string userID = string.Empty;
299
300 if (StringToUrlAndUserID(id, out url, out userID))
301 {
302 //m_log.DebugFormat("[HGInventory CONNECTOR]: calling {0}", url);
303 ISessionAuthInventoryService connector = GetConnector(url);
304 return connector.QueryItem(userID, item, sessionID);
305 }
306 return null;
307 }
308
309 public InventoryFolderBase QueryFolder(string id, InventoryFolderBase folder, UUID sessionID)
310 {
311 string url = string.Empty;
312 string userID = string.Empty;
313
314 if (StringToUrlAndUserID(id, out url, out userID))
315 {
316 ISessionAuthInventoryService connector = GetConnector(url);
317 return connector.QueryFolder(userID, folder, sessionID);
318 }
319 return null;
320 }
321
322 public int GetAssetPermissions(string id, UUID assetID, UUID sessionID)
323 {
324 string url = string.Empty;
325 string userID = string.Empty;
326
327 if (StringToUrlAndUserID(id, out url, out userID))
328 {
329 ISessionAuthInventoryService connector = GetConnector(url);
330 return connector.GetAssetPermissions(userID, assetID, sessionID);
331 }
332 return 0;
333 }
334 }
335}
diff --git a/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs b/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs
deleted file mode 100644
index da8c7e2..0000000
--- a/OpenSim/Services/Connectors/Inventory/ISessionAuthInventoryService.cs
+++ /dev/null
@@ -1,140 +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 OpenSim.Framework;
30using OpenSim.Services.Interfaces;
31using OpenMetaverse;
32
33namespace OpenSim.Services.Connectors
34{
35 /// <summary>
36 /// Defines all operations to access a remote inventory service
37 /// using session authentication as a form of security.
38 /// </summary>
39 public interface ISessionAuthInventoryService
40 {
41 string Host
42 {
43 get;
44 }
45
46 /// <summary>
47 /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
48 /// inventory has been received
49 /// </summary>
50 /// <param name="userID"></param>
51 /// <param name="callback"></param>
52 void GetUserInventory(string userID, UUID session_id, InventoryReceiptCallback callback);
53
54 /// <summary>
55 /// Gets the user folder for the given folder-type
56 /// </summary>
57 /// <param name="userID"></param>
58 /// <param name="type"></param>
59 /// <returns></returns>
60 Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string userID, UUID session_id);
61
62 /// <summary>
63 /// Gets everything (folders and items) inside a folder
64 /// </summary>
65 /// <param name="userId"></param>
66 /// <param name="folderID"></param>
67 /// <returns></returns>
68 InventoryCollection GetFolderContent(string userID, UUID folderID, UUID session_id);
69
70 /// <summary>
71 /// Add a new folder to the user's inventory
72 /// </summary>
73 /// <param name="folder"></param>
74 /// <returns>true if the folder was successfully added</returns>
75 bool AddFolder(string userID, InventoryFolderBase folder, UUID session_id);
76
77 /// <summary>
78 /// Update a folder in the user's inventory
79 /// </summary>
80 /// <param name="folder"></param>
81 /// <returns>true if the folder was successfully updated</returns>
82 bool UpdateFolder(string userID, InventoryFolderBase folder, UUID session_id);
83
84 /// <summary>
85 /// Move an inventory folder to a new location
86 /// </summary>
87 /// <param name="folder">A folder containing the details of the new location</param>
88 /// <returns>true if the folder was successfully moved</returns>
89 bool MoveFolder(string userID, InventoryFolderBase folder, UUID session_id);
90
91 /// <summary>
92 /// Delete a list of inventory folders (from trash)
93 /// </summary>
94 bool DeleteFolders(string userID, List<UUID> folders, UUID session_id);
95
96 /// <summary>
97 /// Purge an inventory folder of all its items and subfolders.
98 /// </summary>
99 /// <param name="folder"></param>
100 /// <returns>true if the folder was successfully purged</returns>
101 bool PurgeFolder(string userID, InventoryFolderBase folder, UUID session_id);
102
103 /// <summary>
104 /// Get items from a folder.
105 /// </summary>
106 /// <param name="folder"></param>
107 /// <returns>true if the folder was successfully purged</returns>
108 List<InventoryItemBase> GetFolderItems(string userID, UUID folderID, UUID session_id);
109
110 /// <summary>
111 /// Add a new item to the user's inventory
112 /// </summary>
113 /// <param name="item"></param>
114 /// <returns>true if the item was successfully added</returns>
115 bool AddItem(string userID, InventoryItemBase item, UUID session_id);
116
117 /// <summary>
118 /// Update an item in the user's inventory
119 /// </summary>
120 /// <param name="item"></param>
121 /// <returns>true if the item was successfully updated</returns>
122 bool UpdateItem(string userID, InventoryItemBase item, UUID session_id);
123
124 bool MoveItems(string userID, List<InventoryItemBase> items, UUID session_id);
125
126 /// <summary>
127 /// Delete an item from the user's inventory
128 /// </summary>
129 /// <param name="item"></param>
130 /// <returns>true if the item was successfully deleted</returns>
131 bool DeleteItems(string userID, List<UUID> itemIDs, UUID session_id);
132
133 InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID session_id);
134
135 InventoryFolderBase QueryFolder(string userID, InventoryFolderBase item, UUID session_id);
136
137 int GetAssetPermissions(string userID, UUID assetID, UUID session_id);
138
139 }
140}
diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
deleted file mode 100644
index f86b453..0000000
--- a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
+++ /dev/null
@@ -1,582 +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.Servers.HttpServer;
36using OpenSim.Services.Interfaces;
37using OpenMetaverse;
38
39namespace OpenSim.Services.Connectors
40{
41 public class InventoryServicesConnector : ISessionAuthInventoryService
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
46
47 private string m_ServerURI = String.Empty;
48
49 private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory = new Dictionary<UUID, InventoryReceiptCallback>();
50 private Dictionary<UUID, DateTime> m_RequestTime = new Dictionary<UUID, DateTime>();
51
52 public InventoryServicesConnector()
53 {
54 }
55
56 public InventoryServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public InventoryServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig inventoryConfig = source.Configs["InventoryService"];
69 if (inventoryConfig == null)
70 {
71 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
72 throw new Exception("InventoryService missing from OpenSim.ini");
73 }
74
75 string serviceURI = inventoryConfig.GetString("InventoryServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
81 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
82 }
83 m_ServerURI = serviceURI.TrimEnd('/');
84 }
85
86 #region ISessionAuthInventoryService
87
88 public string Host
89 {
90 get { return m_ServerURI; }
91 }
92
93 /// <summary>
94 /// Caller must catch eventual Exceptions.
95 /// </summary>
96 /// <param name="userID"></param>
97 /// <param name="sessionID"></param>
98 /// <param name="callback"></param>
99 public void GetUserInventory(string userIDStr, UUID sessionID, InventoryReceiptCallback callback)
100 {
101 UUID userID = UUID.Zero;
102 if (UUID.TryParse(userIDStr, out userID))
103 {
104 lock (m_RequestingInventory)
105 {
106 // *HACK ALERT*
107
108 // If an inventory request times out, it blocks any further requests from the
109 // same user, even after a relog. This is bad, and makes me sad.
110
111 // Really, we should detect a timeout and report a failure to the callback,
112 // BUT in my testing i found that it's hard to detect a timeout.. sometimes,
113 // a partial response is recieved, and sometimes a null response.
114
115 // So, for now, add a timer of ten seconds (which is the request timeout).
116
117 // This should basically have the same effect.
118
119 lock (m_RequestTime)
120 {
121 if (m_RequestTime.ContainsKey(userID))
122 {
123 TimeSpan interval = DateTime.Now - m_RequestTime[userID];
124 if (interval.TotalSeconds > 10)
125 {
126 m_RequestTime.Remove(userID);
127 if (m_RequestingInventory.ContainsKey(userID))
128 {
129 m_RequestingInventory.Remove(userID);
130 }
131 }
132 }
133 if (!m_RequestingInventory.ContainsKey(userID))
134 {
135 m_RequestTime.Add(userID, DateTime.Now);
136 m_RequestingInventory.Add(userID, callback);
137 }
138 else
139 {
140 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetUserInventory - ignoring repeated request for user {0}", userID);
141 return;
142 }
143 }
144 }
145
146 m_log.InfoFormat(
147 "[INVENTORY CONNECTOR]: Requesting inventory from {0}/GetInventory/ for user {1}",
148 m_ServerURI, userID);
149
150 RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
151 = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
152 requester.ResponseCallback = InventoryResponse;
153
154 requester.BeginPostObject(m_ServerURI + "/GetInventory/", userID.Guid, sessionID.ToString(), userID.ToString());
155 }
156 }
157
158 /// <summary>
159 /// Gets the user folder for the given folder-type
160 /// </summary>
161 /// <param name="userID"></param>
162 /// <param name="type"></param>
163 /// <returns></returns>
164 public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(string userID, UUID sessionID)
165 {
166 List<InventoryFolderBase> folders = null;
167 Dictionary<AssetType, InventoryFolderBase> dFolders = new Dictionary<AssetType, InventoryFolderBase>();
168 try
169 {
170 folders = SynchronousRestSessionObjectPoster<Guid, List<InventoryFolderBase>>.BeginPostObject(
171 "POST", m_ServerURI + "/SystemFolders/", new Guid(userID), sessionID.ToString(), userID.ToString());
172
173 foreach (InventoryFolderBase f in folders)
174 dFolders[(AssetType)f.Type] = f;
175
176 return dFolders;
177 }
178 catch (Exception e)
179 {
180 // Maybe we're talking to an old inventory server. Try this other thing.
181 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetSystemFolders operation failed, {0} {1} (old sever?). Trying GetInventory.",
182 e.Source, e.Message);
183
184 try
185 {
186 InventoryCollection inventory = SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
187 "POST", m_ServerURI + "/GetInventory/", new Guid(userID), sessionID.ToString(), userID.ToString());
188 folders = inventory.Folders;
189 }
190 catch (Exception ex)
191 {
192 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetInventory operation also failed, {0} {1}. Giving up.",
193 e.Source, ex.Message);
194 }
195
196 if ((folders != null) && (folders.Count > 0))
197 {
198 m_log.DebugFormat("[INVENTORY CONNECTOR]: Received entire inventory ({0} folders) for user {1}",
199 folders.Count, userID);
200 foreach (InventoryFolderBase f in folders)
201 {
202 if ((f.Type != (short)AssetType.Folder) && (f.Type != (short)AssetType.Unknown))
203 dFolders[(AssetType)f.Type] = f;
204 }
205
206 UUID rootFolderID = dFolders[AssetType.Animation].ParentID;
207 InventoryFolderBase rootFolder = new InventoryFolderBase(rootFolderID, new UUID(userID));
208 rootFolder = QueryFolder(userID, rootFolder, sessionID);
209 dFolders[AssetType.Folder] = rootFolder;
210 m_log.DebugFormat("[INVENTORY CONNECTOR]: {0} system folders for user {1}", dFolders.Count, userID);
211 return dFolders;
212 }
213 }
214
215 return new Dictionary<AssetType, InventoryFolderBase>();
216 }
217
218 /// <summary>
219 /// Gets everything (folders and items) inside a folder
220 /// </summary>
221 /// <param name="userId"></param>
222 /// <param name="folderID"></param>
223 /// <returns></returns>
224 public InventoryCollection GetFolderContent(string userID, UUID folderID, UUID sessionID)
225 {
226 try
227 {
228 // normal case
229 return SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
230 "POST", m_ServerURI + "/GetFolderContent/", folderID.Guid, sessionID.ToString(), userID.ToString());
231 }
232 catch (TimeoutException e)
233 {
234 m_log.ErrorFormat(
235 "[INVENTORY CONNECTOR]: GetFolderContent operation to {0} for {1} timed out {2} {3}.",
236 m_ServerURI, folderID, e.Source, e.Message);
237 }
238 catch (Exception e)
239 {
240 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed for {0}, {1} {2} (old server?).",
241 folderID, e.Source, e.Message);
242 }
243
244 InventoryCollection nullCollection = new InventoryCollection();
245 nullCollection.Folders = new List<InventoryFolderBase>();
246 nullCollection.Items = new List<InventoryItemBase>();
247 nullCollection.UserID = new UUID(userID);
248 return nullCollection;
249 }
250
251 public bool AddFolder(string userID, InventoryFolderBase folder, UUID sessionID)
252 {
253 try
254 {
255 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
256 "POST", m_ServerURI + "/NewFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
257 }
258 catch (Exception e)
259 {
260 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory folder operation failed for {0} {1}, {2} {3}",
261 folder.Name, folder.ID, e.Source, e.Message);
262 }
263
264 return false;
265 }
266
267 public bool UpdateFolder(string userID, InventoryFolderBase folder, UUID sessionID)
268 {
269 try
270 {
271 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
272 "POST", m_ServerURI + "/UpdateFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
273 }
274 catch (Exception e)
275 {
276 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update inventory folder operation failed for {0} {1}, {2} {3}",
277 folder.Name, folder.ID, e.Source, e.Message);
278 }
279
280 return false;
281 }
282
283 public bool DeleteFolders(string userID, List<UUID> folderIDs, UUID sessionID)
284 {
285 try
286 {
287 List<Guid> guids = new List<Guid>();
288 foreach (UUID u in folderIDs)
289 guids.Add(u.Guid);
290 return SynchronousRestSessionObjectPoster<List<Guid>, bool>.BeginPostObject(
291 "POST", m_ServerURI + "/DeleteFolders/", guids, sessionID.ToString(), userID);
292 }
293 catch (Exception e)
294 {
295 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory folders operation failed, {0} {1}",
296 e.Source, e.Message);
297 }
298
299 return false;
300 }
301
302 public bool MoveFolder(string userID, InventoryFolderBase folder, UUID sessionID)
303 {
304 try
305 {
306 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
307 "POST", m_ServerURI + "/MoveFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
308 }
309 catch (Exception e)
310 {
311 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory folder operation failed for {0} {1}, {2} {3}",
312 folder.Name, folder.ID, e.Source, e.Message);
313 }
314
315 return false;
316 }
317
318 public bool PurgeFolder(string userID, InventoryFolderBase folder, UUID sessionID)
319 {
320 try
321 {
322 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
323 "POST", m_ServerURI + "/PurgeFolder/", folder, sessionID.ToString(), folder.Owner.ToString());
324 }
325 catch (Exception e)
326 {
327 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Purge inventory folder operation failed for {0} {1}, {2} {3}",
328 folder.Name, folder.ID, e.Source, e.Message);
329 }
330
331 return false;
332 }
333
334 public List<InventoryItemBase> GetFolderItems(string userID, UUID folderID, UUID sessionID)
335 {
336 try
337 {
338 InventoryFolderBase folder = new InventoryFolderBase(folderID, new UUID(userID));
339 return SynchronousRestSessionObjectPoster<InventoryFolderBase, List<InventoryItemBase>>.BeginPostObject(
340 "POST", m_ServerURI + "/GetItems/", folder, sessionID.ToString(), userID);
341 }
342 catch (Exception e)
343 {
344 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Get folder items operation failed for folder {0}, {1} {2}",
345 folderID, e.Source, e.Message);
346 }
347
348 return null;
349 }
350
351 public bool AddItem(string userID, InventoryItemBase item, UUID sessionID)
352 {
353 try
354 {
355 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
356 "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString());
357 }
358 catch (Exception e)
359 {
360 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Add new inventory item operation failed for {0} {1}, {2} {3}",
361 item.Name, item.ID, e.Source, e.Message);
362 }
363
364 return false;
365 }
366
367 public bool UpdateItem(string userID, InventoryItemBase item, UUID sessionID)
368 {
369 try
370 {
371 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
372 "POST", m_ServerURI + "/NewItem/", item, sessionID.ToString(), item.Owner.ToString());
373 }
374 catch (Exception e)
375 {
376 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Update new inventory item operation failed for {0} {1}, {2} {3}",
377 item.Name, item.ID, e.Source, e.Message);
378 }
379
380 return false;
381 }
382
383 /**
384 * MoveItems Async group
385 */
386
387 delegate void MoveItemsDelegate(string userID, List<InventoryItemBase> items, UUID sessionID);
388
389 private void MoveItemsAsync(string userID, List<InventoryItemBase> items, UUID sessionID)
390 {
391 if (items == null)
392 {
393 m_log.WarnFormat("[INVENTORY CONNECTOR]: request to move items got a null list.");
394 return;
395 }
396
397 try
398 {
399 //SynchronousRestSessionObjectPoster<List<InventoryItemBase>, bool>.BeginPostObject(
400 // "POST", m_ServerURI + "/MoveItems/", items, sessionID.ToString(), userID.ToString());
401
402 //// Success
403 //return;
404 string uri = m_ServerURI + "/inventory/" + userID;
405 if (SynchronousRestObjectRequester.
406 MakeRequest<List<InventoryItemBase>, bool>("PUT", uri, items))
407 m_log.DebugFormat("[INVENTORY CONNECTOR]: move {0} items poster succeeded {1}", items.Count, uri);
408 else
409 m_log.DebugFormat("[INVENTORY CONNECTOR]: move {0} items poster failed {1}", items.Count, uri); ;
410
411 return;
412
413 }
414 catch (Exception e)
415 {
416 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Move inventory items operation failed, {0} {1} (old server?). Trying slow way.",
417 e.Source, e.Message);
418 }
419
420 }
421
422 private void MoveItemsCompleted(IAsyncResult iar)
423 {
424 MoveItemsDelegate d = (MoveItemsDelegate)iar.AsyncState;
425 d.EndInvoke(iar);
426 }
427
428 public bool MoveItems(string userID, List<InventoryItemBase> items, UUID sessionID)
429 {
430 MoveItemsDelegate d = MoveItemsAsync;
431 d.BeginInvoke(userID, items, sessionID, MoveItemsCompleted, d);
432 return true;
433 }
434
435 public bool DeleteItems(string userID, List<UUID> items, UUID sessionID)
436 {
437 try
438 {
439 List<Guid> guids = new List<Guid>();
440 foreach (UUID u in items)
441 guids.Add(u.Guid);
442 return SynchronousRestSessionObjectPoster<List<Guid>, bool>.BeginPostObject(
443 "POST", m_ServerURI + "/DeleteItem/", guids, sessionID.ToString(), userID);
444 }
445 catch (Exception e)
446 {
447 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Delete inventory items operation failed, {0} {1}",
448 e.Source, e.Message);
449 }
450
451 return false;
452 }
453
454 public InventoryItemBase QueryItem(string userID, InventoryItemBase item, UUID sessionID)
455 {
456 try
457 {
458 return SynchronousRestSessionObjectPoster<InventoryItemBase, InventoryItemBase>.BeginPostObject(
459 "POST", m_ServerURI + "/QueryItem/", item, sessionID.ToString(), item.Owner.ToString());
460 }
461 catch (Exception e)
462 {
463 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory item operation failed, {0} {1}",
464 e.Source, e.Message);
465 }
466
467 return null;
468 }
469
470 public InventoryFolderBase QueryFolder(string userID, InventoryFolderBase folder, UUID sessionID)
471 {
472 try
473 {
474 return SynchronousRestSessionObjectPoster<InventoryFolderBase, InventoryFolderBase>.BeginPostObject(
475 "POST", m_ServerURI + "/QueryFolder/", folder, sessionID.ToString(), userID);
476 }
477 catch (Exception e)
478 {
479 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Query inventory folder operation failed, {0} {1}",
480 e.Source, e.Message);
481 }
482
483 return null;
484 }
485
486 public int GetAssetPermissions(string userID, UUID assetID, UUID sessionID)
487 {
488 try
489 {
490 InventoryItemBase item = new InventoryItemBase();
491 item.Owner = new UUID(userID);
492 item.AssetID = assetID;
493 return SynchronousRestSessionObjectPoster<InventoryItemBase, int>.BeginPostObject(
494 "POST", m_ServerURI + "/AssetPermissions/", item, sessionID.ToString(), userID);
495 }
496 catch (Exception e)
497 {
498 m_log.ErrorFormat("[INVENTORY CONNECTOR]: AssetPermissions operation failed, {0} {1}",
499 e.Source, e.Message);
500 }
501
502 return 0;
503 }
504
505 #endregion
506
507 /// <summary>
508 /// Callback used by the inventory server GetInventory request
509 /// </summary>
510 /// <param name="userID"></param>
511 private void InventoryResponse(InventoryCollection response)
512 {
513 UUID userID = response.UserID;
514 InventoryReceiptCallback callback = null;
515 lock (m_RequestingInventory)
516 {
517 if (m_RequestingInventory.ContainsKey(userID))
518 {
519 callback = m_RequestingInventory[userID];
520 m_RequestingInventory.Remove(userID);
521 lock (m_RequestTime)
522 {
523 if (m_RequestTime.ContainsKey(userID))
524 {
525 m_RequestTime.Remove(userID);
526 }
527 }
528 }
529 else
530 {
531 m_log.WarnFormat(
532 "[INVENTORY CONNECTOR]: " +
533 "Received inventory response for {0} for which we do not have a record of requesting!",
534 userID);
535 return;
536 }
537 }
538
539 m_log.InfoFormat("[INVENTORY CONNECTOR]: " +
540 "Received inventory response for user {0} containing {1} folders and {2} items",
541 userID, response.Folders.Count, response.Items.Count);
542
543 InventoryFolderImpl rootFolder = null;
544
545 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
546 ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
547
548 foreach (InventoryFolderBase folder in response.Folders)
549 {
550 if (folder.ParentID == UUID.Zero)
551 {
552 rootFolder = new InventoryFolderImpl(folder);
553 folders.Add(rootFolder);
554
555 break;
556 }
557 }
558
559 if (rootFolder != null)
560 {
561 foreach (InventoryFolderBase folder in response.Folders)
562 {
563 if (folder.ID != rootFolder.ID)
564 {
565 folders.Add(new InventoryFolderImpl(folder));
566 }
567 }
568
569 foreach (InventoryItemBase item in response.Items)
570 {
571 items.Add(item);
572 }
573 }
574 else
575 {
576 m_log.ErrorFormat("[INVENTORY CONNECTOR]: Did not get back an inventory containing a root folder for user {0}", userID);
577 }
578
579 callback(folders, items);
580 }
581 }
582}
diff --git a/OpenSim/Services/Connectors/Inventory/QuickAndDirtyInventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/QuickAndDirtyInventoryServiceConnector.cs
deleted file mode 100644
index a7aa138..0000000
--- a/OpenSim/Services/Connectors/Inventory/QuickAndDirtyInventoryServiceConnector.cs
+++ /dev/null
@@ -1,196 +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.Servers.HttpServer;
36using OpenSim.Services.Interfaces;
37using OpenMetaverse;
38
39namespace OpenSim.Services.Connectors
40{
41 /// <summary>
42 /// This connector is temporary. It's used by the user server, before that server is refactored.
43 /// </summary>
44 public class QuickAndDirtyInventoryServiceConnector : IInventoryService
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 //private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory = new Dictionary<UUID, InventoryReceiptCallback>();
53
54 public QuickAndDirtyInventoryServiceConnector()
55 {
56 }
57
58 public QuickAndDirtyInventoryServiceConnector(string serverURI)
59 {
60 m_ServerURI = serverURI.TrimEnd('/');
61 }
62
63 /// <summary>
64 /// <see cref="OpenSim.Framework.Communications.IInterServiceInventoryServices"/>
65 /// </summary>
66 /// <param name="userId"></param>
67 /// <returns></returns>
68 public bool CreateUserInventory(UUID userId)
69 {
70 return SynchronousRestObjectPoster.BeginPostObject<Guid, bool>(
71 "POST", m_ServerURI + "CreateInventory/", userId.Guid);
72 }
73
74 /// <summary>
75 /// <see cref="OpenSim.Framework.Communications.IInterServiceInventoryServices"/>
76 /// </summary>
77 /// <param name="userId"></param>
78 /// <returns></returns>
79 public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
80 {
81 return SynchronousRestObjectPoster.BeginPostObject<Guid, List<InventoryFolderBase>>(
82 "POST", m_ServerURI + "RootFolders/", userId.Guid);
83 }
84
85 /// <summary>
86 /// Returns a list of all the active gestures in a user's inventory.
87 /// </summary>
88 /// <param name="userId">
89 /// The <see cref="UUID"/> of the user
90 /// </param>
91 /// <returns>
92 /// A flat list of the gesture items.
93 /// </returns>
94 public List<InventoryItemBase> GetActiveGestures(UUID userId)
95 {
96 return SynchronousRestObjectPoster.BeginPostObject<Guid, List<InventoryItemBase>>(
97 "POST", m_ServerURI + "ActiveGestures/", userId.Guid);
98 }
99
100 public InventoryCollection GetUserInventory(UUID userID)
101 {
102 return null;
103 }
104
105 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
106 {
107 }
108
109 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
110 {
111 return null;
112 }
113
114 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
115 {
116 return null;
117 }
118
119 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
120 {
121 return null;
122 }
123
124 public bool AddFolder(InventoryFolderBase folder)
125 {
126 return false;
127 }
128
129 public bool UpdateFolder(InventoryFolderBase folder)
130 {
131 return false;
132 }
133
134 public bool MoveFolder(InventoryFolderBase folder)
135 {
136 return false;
137 }
138
139 public bool DeleteFolders(UUID ownerID, List<UUID> folderIDs)
140 {
141 return false;
142 }
143
144
145 public bool PurgeFolder(InventoryFolderBase folder)
146 {
147 return false;
148 }
149
150 public bool AddItem(InventoryItemBase item)
151 {
152 return false;
153 }
154
155 public bool UpdateItem(InventoryItemBase item)
156 {
157 return false;
158 }
159
160 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
161 {
162 return false;
163 }
164
165 public bool DeleteItems(UUID owner, List<UUID> itemIDs)
166 {
167 return false;
168 }
169
170 public InventoryItemBase GetItem(InventoryItemBase item)
171 {
172 return null;
173 }
174
175 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
176 {
177 return null;
178 }
179
180 public bool HasInventoryForUser(UUID userID)
181 {
182 return false;
183 }
184
185 public InventoryFolderBase GetRootFolder(UUID userID)
186 {
187 return null;
188 }
189
190 public int GetAssetPermissions(UUID userID, UUID assetID)
191 {
192 return 0;
193 }
194
195 }
196}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
new file mode 100644
index 0000000..93fdae3
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.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.Reflection;
31using System.Net;
32using System.IO;
33using System.Timers;
34using System.Drawing;
35using System.Drawing.Imaging;
36
37using log4net;
38using Mono.Addins;
39using Nini.Config;
40using OpenSim.Framework;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using OpenMetaverse;
44using OpenMetaverse.StructuredData;
45
46namespace OpenSim.Region.OptionalModules.Simian
47{
48 /// <summary>
49 /// </summary>
50 /// <remarks>
51 /// </remarks>
52
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianGridMaptile")]
54 public class SimianGridMaptile : ISharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58
59 private bool m_enabled = false;
60 private string m_serverUrl = String.Empty;
61 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
62
63 private int m_refreshtime = 0;
64 private int m_lastrefresh = 0;
65 private System.Timers.Timer m_refreshTimer = new System.Timers.Timer();
66
67 #region ISharedRegionModule
68
69 public Type ReplaceableInterface { get { return null; } }
70 public string Name { get { return "SimianGridMaptile"; } }
71 public void RegionLoaded(Scene scene) { }
72 public void Close() { }
73
74 ///<summary>
75 ///
76 ///</summary>
77 public void Initialise(IConfigSource source)
78 {
79 IConfig config = source.Configs["SimianGridMaptiles"];
80 if (config == null)
81 return;
82
83 if (! config.GetBoolean("Enabled", false))
84 return;
85
86 m_serverUrl = config.GetString("MaptileURL");
87 if (String.IsNullOrEmpty(m_serverUrl))
88 return;
89
90 int refreshseconds = Convert.ToInt32(config.GetString("RefreshTime"));
91 if (refreshseconds <= 0)
92 return;
93
94 m_refreshtime = refreshseconds * 1000; // convert from seconds to ms
95 m_log.InfoFormat("[SIMIAN MAPTILE] enabled with refresh timeout {0} and URL {1}",
96 m_refreshtime,m_serverUrl);
97
98 m_enabled = true;
99 }
100
101 ///<summary>
102 ///
103 ///</summary>
104 public void PostInitialise()
105 {
106 if (m_enabled)
107 {
108 m_refreshTimer.Enabled = true;
109 m_refreshTimer.AutoReset = true;
110 m_refreshTimer.Interval = 5 * 60 * 1000; // every 5 minutes
111 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
112 }
113 }
114
115
116 ///<summary>
117 ///
118 ///</summary>
119 public void AddRegion(Scene scene)
120 {
121 if (! m_enabled)
122 return;
123
124 // Every shared region module has to maintain an indepedent list of
125 // currently running regions
126 lock (m_scenes)
127 m_scenes[scene.RegionInfo.RegionID] = scene;
128 }
129
130 ///<summary>
131 ///
132 ///</summary>
133 public void RemoveRegion(Scene scene)
134 {
135 if (! m_enabled)
136 return;
137
138 lock (m_scenes)
139 m_scenes.Remove(scene.RegionInfo.RegionID);
140 }
141
142 #endregion ISharedRegionModule
143
144 ///<summary>
145 ///
146 ///</summary>
147 private void HandleMaptileRefresh(object sender, EventArgs ea)
148 {
149 // this approach is a bit convoluted becase we want to wait for the
150 // first upload to happen on startup but after all the objects are
151 // loaded and initialized
152 if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime)
153 return;
154
155 m_log.DebugFormat("[SIMIAN MAPTILE] map refresh fired");
156 lock (m_scenes)
157 {
158 foreach (IScene scene in m_scenes.Values)
159 {
160 try
161 {
162 UploadMapTile(scene);
163 }
164 catch (Exception ex)
165 {
166 m_log.WarnFormat("[SIMIAN MAPTILE] something bad happened {0}",ex.Message);
167 }
168 }
169 }
170
171 m_lastrefresh = Util.EnvironmentTickCount();
172 }
173
174 ///<summary>
175 ///
176 ///</summary>
177 private void UploadMapTile(IScene scene)
178 {
179 m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for {0}",scene.RegionInfo.RegionName);
180
181 // Create a PNG map tile and upload it to the AddMapTile API
182 byte[] pngData = Utils.EmptyBytes;
183 IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
184 if (tileGenerator == null)
185 {
186 m_log.Warn("[SIMIAN MAPTILE]: Cannot upload PNG map tile without an ImageGenerator");
187 return;
188 }
189
190 using (Image mapTile = tileGenerator.CreateMapTile())
191 {
192 using (MemoryStream stream = new MemoryStream())
193 {
194 mapTile.Save(stream, ImageFormat.Png);
195 pngData = stream.ToArray();
196 }
197 }
198
199 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
200 {
201 new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
202 new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
203 new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
204 };
205
206 string errorMessage = null;
207 int tickstart = Util.EnvironmentTickCount();
208
209 // Make the remote storage request
210 try
211 {
212 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
213 request.Timeout = 20000;
214 request.ReadWriteTimeout = 5000;
215
216 using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
217 {
218 using (Stream responseStream = response.GetResponseStream())
219 {
220 string responseStr = responseStream.GetStreamString();
221 OSD responseOSD = OSDParser.Deserialize(responseStr);
222 if (responseOSD.Type == OSDType.Map)
223 {
224 OSDMap responseMap = (OSDMap)responseOSD;
225 if (responseMap["Success"].AsBoolean())
226 return;
227
228 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
229 }
230 else
231 {
232 errorMessage = "Response format was invalid:\n" + responseStr;
233 }
234 }
235 }
236 }
237 catch (WebException we)
238 {
239 errorMessage = we.Message;
240 if (we.Status == WebExceptionStatus.ProtocolError)
241 {
242 HttpWebResponse webResponse = (HttpWebResponse)we.Response;
243 errorMessage = String.Format("[{0}] {1}",
244 webResponse.StatusCode,webResponse.StatusDescription);
245 }
246 }
247 catch (Exception ex)
248 {
249 errorMessage = ex.Message;
250 }
251 finally
252 {
253 // This just dumps a warning for any operation that takes more than 100 ms
254 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
255 m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms",tickdiff);
256 }
257
258 m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}",
259 pngData.Length, scene.RegionInfo.RegionName, errorMessage);
260 }
261 }
262} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 2c8277f..46ad9dd 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -48,6 +48,9 @@ namespace OpenSim.Services.Connectors.Simulation
48 { 48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 // we use this dictionary to track the pending updateagent requests, maps URI --> position update
52 private Dictionary<string,AgentPosition> m_updateAgentQueue = new Dictionary<string,AgentPosition>();
53
51 //private GridRegion m_Region; 54 //private GridRegion m_Region;
52 55
53 public SimulationServiceConnector() 56 public SimulationServiceConnector()
@@ -133,10 +136,56 @@ namespace OpenSim.Services.Connectors.Simulation
133 /// </summary> 136 /// </summary>
134 public bool UpdateAgent(GridRegion destination, AgentPosition data) 137 public bool UpdateAgent(GridRegion destination, AgentPosition data)
135 { 138 {
136 // we need a better throttle for these 139 // The basic idea of this code is that the first thread that needs to
137 // return false; 140 // send an update for a specific avatar becomes the worker for any subsequent
141 // requests until there are no more outstanding requests. Further, only send the most
142 // recent update; this *should* never be needed but some requests get
143 // slowed down and once that happens the problem with service end point
144 // limits kicks in and nothing proceeds
145 string uri = destination.ServerURI + AgentPath() + data.AgentID + "/";
146 lock (m_updateAgentQueue)
147 {
148 if (m_updateAgentQueue.ContainsKey(uri))
149 {
150 // Another thread is already handling
151 // updates for this simulator, just update
152 // the position and return, overwrites are
153 // not a problem since we only care about the
154 // last update anyway
155 m_updateAgentQueue[uri] = data;
156 return true;
157 }
158
159 // Otherwise update the reference and start processing
160 m_updateAgentQueue[uri] = data;
161 }
138 162
139 return UpdateAgent(destination, (IAgentData)data); 163 AgentPosition pos = null;
164 while (true)
165 {
166 lock (m_updateAgentQueue)
167 {
168 // save the position
169 AgentPosition lastpos = pos;
170
171 pos = m_updateAgentQueue[uri];
172
173 // this is true if no one put a new
174 // update in the map since the last
175 // one we processed, if thats the
176 // case then we are done
177 if (pos == lastpos)
178 {
179 m_updateAgentQueue.Remove(uri);
180 return true;
181 }
182 }
183
184 UpdateAgent(destination,(IAgentData)pos);
185 }
186
187 // unreachable
188 return true;
140 } 189 }
141 190
142 /// <summary> 191 /// <summary>
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 125c2be..aeff9b5 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -286,7 +286,7 @@ namespace OpenSim.Services.GridService
286 } 286 }
287 287
288 } 288 }
289 m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighours", region.RegionName, rinfos.Count); 289 m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count);
290 return rinfos; 290 return rinfos;
291 } 291 }
292 292
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
index c02c813..e0d8103 100644
--- a/OpenSim/Services/GridService/HypergridLinker.cs
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -180,44 +180,18 @@ namespace OpenSim.Services.GridService
180 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason) 180 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason)
181 { 181 {
182 reason = string.Empty; 182 reason = string.Empty;
183 string host = "127.0.0.1";
184 string portstr;
185 string regionName = "";
186 uint port = 0; 183 uint port = 0;
187 string[] parts = mapName.Split(new char[] { ':' }); 184 string[] parts = mapName.Split(new char[] {':'});
188 if (parts.Length >= 1) 185 string regionName = String.Empty;
186 if (parts.Length > 1)
189 { 187 {
190 host = parts[0]; 188 regionName = mapName.Substring(parts[0].Length + 1);
189 regionName = regionName.Trim(new char[] {'"'});
191 } 190 }
192 if (parts.Length >= 2)
193 {
194 portstr = parts[1];
195 //m_log.Debug("-- port = " + portstr);
196 if (!UInt32.TryParse(portstr, out port))
197 regionName = parts[1];
198 }
199 // always take the last one
200 if (parts.Length >= 3)
201 {
202 regionName = parts[2];
203 }
204
205 //// Sanity check.
206 //try
207 //{
208 // Util.GetHostFromDNS(host);
209 //}
210 //catch
211 //{
212 // reason = "Malformed hostname";
213 // return null;
214 //}
215
216 GridRegion regInfo; 191 GridRegion regInfo;
217 bool success = TryCreateLink(scopeID, xloc, yloc, regionName, port, host, ownerID, out regInfo, out reason); 192 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason))
218 if (success)
219 { 193 {
220 regInfo.RegionName = mapName; 194 regInfo.RegionName = mapName;
221 return regInfo; 195 return regInfo;
222 } 196 }
223 197
@@ -313,9 +287,9 @@ namespace OpenSim.Services.GridService
313 287
314 regInfo.RegionID = regionID; 288 regInfo.RegionID = regionID;
315 289
316 if ( externalName == string.Empty ) 290 if (externalName == string.Empty)
317 regInfo.RegionName = regInfo.ServerURI; 291 regInfo.RegionName = regInfo.ServerURI;
318 else 292 else
319 regInfo.RegionName = externalName; 293 regInfo.RegionName = externalName;
320 294
321 m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName); 295 m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName);