diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage')
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs | 137 |
1 files changed, 105 insertions, 32 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index a839086..08d6bdd 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs | |||
@@ -53,10 +53,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
53 | /// </remarks> | 53 | /// </remarks> |
54 | 54 | ||
55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapImageServiceModule")] | 55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapImageServiceModule")] |
56 | public class MapImageServiceModule : ISharedRegionModule | 56 | public class MapImageServiceModule : IMapImageUploadModule, ISharedRegionModule |
57 | { | 57 | { |
58 | private static readonly ILog m_log = | 58 | private static readonly ILog m_log = |
59 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 59 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
60 | private static string LogHeader = "[MAP IMAGE SERVICE MODULE]:"; | ||
60 | 61 | ||
61 | private bool m_enabled = false; | 62 | private bool m_enabled = false; |
62 | private IMapImageService m_MapService; | 63 | private IMapImageService m_MapService; |
@@ -65,7 +66,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
65 | 66 | ||
66 | private int m_refreshtime = 0; | 67 | private int m_refreshtime = 0; |
67 | private int m_lastrefresh = 0; | 68 | private int m_lastrefresh = 0; |
68 | private System.Timers.Timer m_refreshTimer = new System.Timers.Timer(); | 69 | private System.Timers.Timer m_refreshTimer; |
69 | 70 | ||
70 | #region ISharedRegionModule | 71 | #region ISharedRegionModule |
71 | 72 | ||
@@ -75,7 +76,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
75 | public void Close() { } | 76 | public void Close() { } |
76 | public void PostInitialise() { } | 77 | public void PostInitialise() { } |
77 | 78 | ||
78 | |||
79 | ///<summary> | 79 | ///<summary> |
80 | /// | 80 | /// |
81 | ///</summary> | 81 | ///</summary> |
@@ -94,14 +94,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
94 | return; | 94 | return; |
95 | 95 | ||
96 | int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); | 96 | int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); |
97 | if (refreshminutes <= 0) | 97 | |
98 | // if refresh is less than zero, disable the module | ||
99 | if (refreshminutes < 0) | ||
98 | { | 100 | { |
99 | m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled."); | 101 | m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Negative refresh time given in config. Module disabled."); |
100 | return; | 102 | return; |
101 | } | 103 | } |
102 | 104 | ||
103 | m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms | ||
104 | |||
105 | string service = config.GetString("LocalServiceModule", string.Empty); | 105 | string service = config.GetString("LocalServiceModule", string.Empty); |
106 | if (service == string.Empty) | 106 | if (service == string.Empty) |
107 | { | 107 | { |
@@ -116,15 +116,25 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
116 | m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Unable to load LocalServiceModule from {0}. MapService module disabled. Please fix the configuration.", service); | 116 | m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Unable to load LocalServiceModule from {0}. MapService module disabled. Please fix the configuration.", service); |
117 | return; | 117 | return; |
118 | } | 118 | } |
119 | |||
120 | // we don't want the timer if the interval is zero, but we still want this module enables | ||
121 | if(refreshminutes > 0) | ||
122 | { | ||
123 | m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms | ||
124 | |||
125 | m_refreshTimer = new System.Timers.Timer(); | ||
126 | m_refreshTimer.Enabled = true; | ||
127 | m_refreshTimer.AutoReset = true; | ||
128 | m_refreshTimer.Interval = m_refreshtime; | ||
129 | m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); | ||
119 | 130 | ||
120 | m_refreshTimer.Enabled = true; | 131 | m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0} min and service object {1}", |
121 | m_refreshTimer.AutoReset = true; | ||
122 | m_refreshTimer.Interval = m_refreshtime; | ||
123 | m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); | ||
124 | |||
125 | m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}", | ||
126 | refreshminutes, service); | 132 | refreshminutes, service); |
127 | 133 | } | |
134 | else | ||
135 | { | ||
136 | m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with no refresh and service object {0}", service); | ||
137 | } | ||
128 | m_enabled = true; | 138 | m_enabled = true; |
129 | } | 139 | } |
130 | 140 | ||
@@ -133,7 +143,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
133 | ///</summary> | 143 | ///</summary> |
134 | public void AddRegion(Scene scene) | 144 | public void AddRegion(Scene scene) |
135 | { | 145 | { |
136 | if (! m_enabled) | 146 | if (!m_enabled) |
137 | return; | 147 | return; |
138 | 148 | ||
139 | // Every shared region module has to maintain an indepedent list of | 149 | // Every shared region module has to maintain an indepedent list of |
@@ -141,7 +151,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
141 | lock (m_scenes) | 151 | lock (m_scenes) |
142 | m_scenes[scene.RegionInfo.RegionID] = scene; | 152 | m_scenes[scene.RegionInfo.RegionID] = scene; |
143 | 153 | ||
144 | scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) UploadMapTile(s); }; | 154 | // v2 Map generation on startup is now handled by scene to allow bmp to be shared with |
155 | // v1 service and not generate map tiles twice as was previous behavior | ||
156 | //scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) UploadMapTile(s); }; | ||
157 | |||
158 | scene.RegisterModuleInterface<IMapImageUploadModule>(this); | ||
145 | } | 159 | } |
146 | 160 | ||
147 | ///<summary> | 161 | ///<summary> |
@@ -188,42 +202,101 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
188 | m_lastrefresh = Util.EnvironmentTickCount(); | 202 | m_lastrefresh = Util.EnvironmentTickCount(); |
189 | } | 203 | } |
190 | 204 | ||
205 | public void UploadMapTile(IScene scene, Bitmap mapTile) | ||
206 | { | ||
207 | if (mapTile == null) | ||
208 | { | ||
209 | m_log.WarnFormat("{0} Cannot upload null image", LogHeader); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | m_log.DebugFormat("{0} Upload maptile for {1}", LogHeader, scene.Name); | ||
214 | |||
215 | // mapTile.Save( // DEBUG DEBUG | ||
216 | // String.Format("maptiles/raw-{0}-{1}-{2}.jpg", regionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY), | ||
217 | // ImageFormat.Jpeg); | ||
218 | // If the region/maptile is legacy sized, just upload the one tile like it has always been done | ||
219 | if (mapTile.Width == Constants.RegionSize && mapTile.Height == Constants.RegionSize) | ||
220 | { | ||
221 | ConvertAndUploadMaptile(mapTile, | ||
222 | scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, | ||
223 | scene.RegionInfo.RegionName); | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | // For larger regions (varregion) we must cut the region image into legacy sized | ||
228 | // pieces since that is how the maptile system works. | ||
229 | // Note the assumption that varregions are always a multiple of legacy size. | ||
230 | for (uint xx = 0; xx < mapTile.Width; xx += Constants.RegionSize) | ||
231 | { | ||
232 | for (uint yy = 0; yy < mapTile.Height; yy += Constants.RegionSize) | ||
233 | { | ||
234 | // Images are addressed from the upper left corner so have to do funny | ||
235 | // math to pick out the sub-tile since regions are numbered from | ||
236 | // the lower left. | ||
237 | Rectangle rect = new Rectangle( | ||
238 | (int)xx, | ||
239 | mapTile.Height - (int)yy - (int)Constants.RegionSize, | ||
240 | (int)Constants.RegionSize, (int)Constants.RegionSize); | ||
241 | using (Bitmap subMapTile = mapTile.Clone(rect, mapTile.PixelFormat)) | ||
242 | { | ||
243 | ConvertAndUploadMaptile(subMapTile, | ||
244 | scene.RegionInfo.RegionLocX + (xx / Constants.RegionSize), | ||
245 | scene.RegionInfo.RegionLocY + (yy / Constants.RegionSize), | ||
246 | scene.Name); | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | |||
191 | ///<summary> | 253 | ///<summary> |
192 | /// | 254 | /// |
193 | ///</summary> | 255 | ///</summary> |
194 | private void UploadMapTile(IScene scene) | 256 | private void UploadMapTile(IScene scene) |
195 | { | 257 | { |
196 | m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName); | ||
197 | |||
198 | // Create a JPG map tile and upload it to the AddMapTile API | 258 | // Create a JPG map tile and upload it to the AddMapTile API |
199 | byte[] jpgData = Utils.EmptyBytes; | ||
200 | IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>(); | 259 | IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>(); |
201 | if (tileGenerator == null) | 260 | if (tileGenerator == null) |
202 | { | 261 | { |
203 | m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator"); | 262 | m_log.WarnFormat("{0} Cannot upload map tile without an ImageGenerator", LogHeader); |
204 | return; | 263 | return; |
205 | } | 264 | } |
206 | 265 | ||
207 | using (Image mapTile = tileGenerator.CreateMapTile()) | 266 | using (Bitmap mapTile = tileGenerator.CreateMapTile()) |
208 | { | 267 | { |
209 | using (MemoryStream stream = new MemoryStream()) | 268 | if (mapTile != null) |
269 | { | ||
270 | UploadMapTile(scene, mapTile); | ||
271 | } | ||
272 | else | ||
210 | { | 273 | { |
211 | mapTile.Save(stream, ImageFormat.Jpeg); | 274 | m_log.WarnFormat("{0} Tile image generation failed", LogHeader); |
212 | jpgData = stream.ToArray(); | ||
213 | } | 275 | } |
214 | } | 276 | } |
277 | } | ||
215 | 278 | ||
216 | if (jpgData == Utils.EmptyBytes) | 279 | private void ConvertAndUploadMaptile(Image tileImage, uint locX, uint locY, string regionName) |
280 | { | ||
281 | byte[] jpgData = Utils.EmptyBytes; | ||
282 | |||
283 | using (MemoryStream stream = new MemoryStream()) | ||
217 | { | 284 | { |
218 | m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: Tile image generation failed"); | 285 | tileImage.Save(stream, ImageFormat.Jpeg); |
219 | return; | 286 | jpgData = stream.ToArray(); |
220 | } | 287 | } |
221 | 288 | if (jpgData != Utils.EmptyBytes) | |
222 | string reason = string.Empty; | 289 | { |
223 | if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason)) | 290 | string reason = string.Empty; |
291 | if (!m_MapService.AddMapTile((int)locX, (int)locY, jpgData, out reason)) | ||
292 | { | ||
293 | m_log.DebugFormat("{0} Unable to upload tile image for {1} at {2}-{3}: {4}", LogHeader, | ||
294 | regionName, locX, locY, reason); | ||
295 | } | ||
296 | } | ||
297 | else | ||
224 | { | 298 | { |
225 | m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}", | 299 | m_log.WarnFormat("{0} Tile image generation failed for region {1}", LogHeader, regionName); |
226 | scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason); | ||
227 | } | 300 | } |
228 | } | 301 | } |
229 | } | 302 | } |