aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/Connectors/SimianGrid
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/Connectors/SimianGrid')
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs261
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs86
2 files changed, 261 insertions, 86 deletions
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
new file mode 100644
index 0000000..dd8fe2b
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
@@ -0,0 +1,261 @@
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 m_refreshtime = Convert.ToInt32(config.GetString("RefreshTime"));
91 if (m_refreshtime <= 0)
92 return;
93
94 m_log.InfoFormat("[SIMIAN MAPTILE] enabled with refresh timeout {0} and URL {1}",
95 m_refreshtime,m_serverUrl);
96
97 m_enabled = true;
98 }
99
100 ///<summary>
101 ///
102 ///</summary>
103 public void PostInitialise()
104 {
105 if (m_enabled)
106 {
107 m_refreshTimer.Enabled = true;
108 m_refreshTimer.AutoReset = true;
109 m_refreshTimer.Interval = 5 * 60 * 1000; // every 5 minutes
110 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
111 }
112 }
113
114
115 ///<summary>
116 ///
117 ///</summary>
118 public void AddRegion(Scene scene)
119 {
120 if (! m_enabled)
121 return;
122
123 // Every shared region module has to maintain an indepedent list of
124 // currently running regions
125 lock (m_scenes)
126 m_scenes[scene.RegionInfo.RegionID] = scene;
127 }
128
129 ///<summary>
130 ///
131 ///</summary>
132 public void RemoveRegion(Scene scene)
133 {
134 if (! m_enabled)
135 return;
136
137 lock (m_scenes)
138 m_scenes.Remove(scene.RegionInfo.RegionID);
139 }
140
141 #endregion ISharedRegionModule
142
143 ///<summary>
144 ///
145 ///</summary>
146 private void HandleMaptileRefresh(object sender, EventArgs ea)
147 {
148 // this approach is a bit convoluted becase we want to wait for the
149 // first upload to happen on startup but after all the objects are
150 // loaded and initialized
151 if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime)
152 return;
153
154 m_log.DebugFormat("[SIMIAN MAPTILE] map refresh fired");
155 lock (m_scenes)
156 {
157 foreach (IScene scene in m_scenes.Values)
158 {
159 try
160 {
161 UploadMapTile(scene);
162 }
163 catch (Exception ex)
164 {
165 m_log.WarnFormat("[SIMIAN MAPTILE] something bad happened {0}",ex.Message);
166 }
167 }
168 }
169
170 m_lastrefresh = Util.EnvironmentTickCount();
171 }
172
173 ///<summary>
174 ///
175 ///</summary>
176 private void UploadMapTile(IScene scene)
177 {
178 m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for {0}",scene.RegionInfo.RegionName);
179
180 // Create a PNG map tile and upload it to the AddMapTile API
181 byte[] pngData = Utils.EmptyBytes;
182 IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
183 if (tileGenerator == null)
184 {
185 m_log.Warn("[SIMIAN MAPTILE]: Cannot upload PNG map tile without an ImageGenerator");
186 return;
187 }
188
189 using (Image mapTile = tileGenerator.CreateMapTile())
190 {
191 using (MemoryStream stream = new MemoryStream())
192 {
193 mapTile.Save(stream, ImageFormat.Png);
194 pngData = stream.ToArray();
195 }
196 }
197
198 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
199 {
200 new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
201 new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
202 new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
203 };
204
205 string errorMessage = null;
206 int tickstart = Util.EnvironmentTickCount();
207
208 // Make the remote storage request
209 try
210 {
211 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
212 request.Timeout = 20000;
213 request.ReadWriteTimeout = 5000;
214
215 using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
216 {
217 using (Stream responseStream = response.GetResponseStream())
218 {
219 string responseStr = responseStream.GetStreamString();
220 OSD responseOSD = OSDParser.Deserialize(responseStr);
221 if (responseOSD.Type == OSDType.Map)
222 {
223 OSDMap responseMap = (OSDMap)responseOSD;
224 if (responseMap["Success"].AsBoolean())
225 return;
226
227 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
228 }
229 else
230 {
231 errorMessage = "Response format was invalid:\n" + responseStr;
232 }
233 }
234 }
235 }
236 catch (WebException we)
237 {
238 errorMessage = we.Message;
239 if (we.Status == WebExceptionStatus.ProtocolError)
240 {
241 HttpWebResponse webResponse = (HttpWebResponse)we.Response;
242 errorMessage = String.Format("[{0}] {1}",
243 webResponse.StatusCode,webResponse.StatusDescription);
244 }
245 }
246 catch (Exception ex)
247 {
248 errorMessage = ex.Message;
249 }
250 finally
251 {
252 // This just dumps a warning for any operation that takes more than 100 ms
253 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
254 m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms",tickdiff);
255 }
256
257 m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}",
258 pngData.Length, scene.RegionInfo.RegionName, errorMessage);
259 }
260 }
261} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
index 9c72a61..18a31670 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
@@ -28,8 +28,6 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Collections.Specialized; 30using System.Collections.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.IO; 31using System.IO;
34using System.Net; 32using System.Net;
35using System.Reflection; 33using System.Reflection;
@@ -102,13 +100,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
102 100
103 public string RegisterRegion(UUID scopeID, GridRegion regionInfo) 101 public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
104 { 102 {
105 // Generate and upload our map tile in PNG format to the SimianGrid AddMapTile service
106// Scene scene;
107// if (m_scenes.TryGetValue(regionInfo.RegionID, out scene))
108// UploadMapTile(scene);
109// else
110// m_log.Warn("Registering region " + regionInfo.RegionName + " (" + regionInfo.RegionID + ") that we are not tracking");
111
112 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0); 103 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
113 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0); 104 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0);
114 105
@@ -380,83 +371,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
380 371
381 #endregion IGridService 372 #endregion IGridService
382 373
383 private void UploadMapTile(IScene scene)
384 {
385 string errorMessage = null;
386
387 // Create a PNG map tile and upload it to the AddMapTile API
388 byte[] pngData = Utils.EmptyBytes;
389 IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
390 if (tileGenerator == null)
391 {
392 m_log.Warn("[SIMIAN GRID CONNECTOR]: Cannot upload PNG map tile without an IMapImageGenerator");
393 return;
394 }
395
396 using (Image mapTile = tileGenerator.CreateMapTile())
397 {
398 using (MemoryStream stream = new MemoryStream())
399 {
400 mapTile.Save(stream, ImageFormat.Png);
401 pngData = stream.ToArray();
402 }
403 }
404
405 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
406 {
407 new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
408 new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
409 new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
410 };
411
412 // Make the remote storage request
413 try
414 {
415 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI);
416
417 HttpWebResponse response = MultipartForm.Post(request, postParameters);
418 using (Stream responseStream = response.GetResponseStream())
419 {
420 string responseStr = null;
421
422 try
423 {
424 responseStr = responseStream.GetStreamString();
425 OSD responseOSD = OSDParser.Deserialize(responseStr);
426 if (responseOSD.Type == OSDType.Map)
427 {
428 OSDMap responseMap = (OSDMap)responseOSD;
429 if (responseMap["Success"].AsBoolean())
430 m_log.Info("[SIMIAN GRID CONNECTOR]: Uploaded " + pngData.Length + " byte PNG map tile to AddMapTile");
431 else
432 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
433 }
434 else
435 {
436 errorMessage = "Response format was invalid:\n" + responseStr;
437 }
438 }
439 catch (Exception ex)
440 {
441 if (!String.IsNullOrEmpty(responseStr))
442 errorMessage = "Failed to parse the response:\n" + responseStr;
443 else
444 errorMessage = "Failed to retrieve the response: " + ex.Message;
445 }
446 }
447 }
448 catch (WebException ex)
449 {
450 errorMessage = ex.Message;
451 }
452
453 if (!String.IsNullOrEmpty(errorMessage))
454 {
455 m_log.WarnFormat("[SIMIAN GRID CONNECTOR]: Failed to store {0} byte PNG map tile for {1}: {2}",
456 pngData.Length, scene.RegionInfo.RegionName, errorMessage.Replace('\n', ' '));
457 }
458 }
459
460 private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled) 374 private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled)
461 { 375 {
462 NameValueCollection requestArgs = new NameValueCollection 376 NameValueCollection requestArgs = new NameValueCollection