From d99277939750247ad100395394720c73a3580c72 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 11 Jun 2011 09:36:57 -0700 Subject: Switched order of SQL statements in Friends migration -- resulted in the wrong key --- OpenSim/Data/MySQL/Resources/FriendsStore.migrations | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations index 7848e49..55d82ec 100644 --- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations +++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations @@ -25,8 +25,8 @@ COMMIT; BEGIN; +ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; ALTER TABLE `Friends` DROP PRIMARY KEY; ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36)); -ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'; COMMIT; -- cgit v1.1 From e1ca77a0dbc68431131b0505f03cf45dbfe5b7d9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 11 Jun 2011 17:22:35 -0700 Subject: Only send AgentOnline to the client if the friendsOnline list has elements. Also, increased the timeout on UserAgentServiceConnector, StatusNotification again. --- OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 2 +- OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 40506a5..2c91514 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -284,7 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends List friendsOnline = uConn.StatusNotification(ids, userID, online); Thread.Sleep(100); // need to debug this here - if (online) + if (online && friendsOnline.Count > 0) { IClientAPI client = LocateClientObject(userID); if (client != null) diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 2a5fb40..6265bcd 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -436,7 +436,7 @@ namespace OpenSim.Services.Connectors.Hypergrid XmlRpcResponse response = null; try { - response = request.Send(m_ServerURL, 4000); + response = request.Send(m_ServerURL, 6000); } catch (Exception e) { -- cgit v1.1 From 06e254c392c754bf7e7a1c80400a3ef5b1a82ca3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 11 Jun 2011 17:48:19 -0700 Subject: A few more cleanups on the way to close http://opensimulator.org/mantis/view.php?id=5516 once and for all. Moral of the story: don't send AgentOnline/Offline to viewers with a zero-length array. --- .../Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 2c91514..dda67f9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -280,10 +280,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends List ids = new List(); foreach (FriendInfo f in kvp.Value) ids.Add(f.Friend); - UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key, false); + UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key); List friendsOnline = uConn.StatusNotification(ids, userID, online); - Thread.Sleep(100); - // need to debug this here + if (online && friendsOnline.Count > 0) { IClientAPI client = LocateClientObject(userID); @@ -305,15 +304,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) { IUserManagement userMan = m_Scenes[0].RequestModuleInterface(); - userMan.AddUser(agentID, url + ";" + first + " " + last); + userMan.AddUser(agentID, first, last, url); - try // our best - { - string[] parts = userMan.GetUserName(agentID).Split(); - first = parts[0]; - last = parts[1]; - } - catch { } return true; } return false; -- cgit v1.1 From fd57c91b4a10cf7ee1e94dc8fe4e81eb0d5bae3d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 15:37:42 -0700 Subject: First pass at making the V2 map work. Standalones only for now. There are some issues with the zoom level -- TBD. --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 4 +- .../MapImage/MapImageServiceInConnectorModule.cs | 111 ++++++++ .../MapImage/MapImageServiceModule.cs | 232 ++++++++++++++++ .../CoreModules/World/WorldMap/WorldMapModule.cs | 8 +- .../Server/Handlers/Map/MapAddServerConnector.cs | 61 +++++ .../Server/Handlers/Map/MapGetServerConnector.cs | 105 ++++++++ .../MapImage/MapImageServiceConnector.cs | 158 +++++++++++ OpenSim/Services/Interfaces/IMapImageService.cs | 40 +++ OpenSim/Services/Interfaces/IMapService.cs | 38 --- .../Services/MapImageService/MapImageService.cs | 295 +++++++++++++++++++++ bin/config-include/Standalone.ini | 7 + bin/config-include/StandaloneCommon.ini.example | 3 + bin/config-include/StandaloneHypergrid.ini | 11 +- prebuild.xml | 30 +++ 14 files changed, 1057 insertions(+), 46 deletions(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs create mode 100644 OpenSim/Server/Handlers/Map/MapAddServerConnector.cs create mode 100644 OpenSim/Server/Handlers/Map/MapGetServerConnector.cs create mode 100644 OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs create mode 100644 OpenSim/Services/Interfaces/IMapImageService.cs delete mode 100644 OpenSim/Services/Interfaces/IMapService.cs create mode 100644 OpenSim/Services/MapImageService/MapImageService.cs diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 598e5d1..cb1117a 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -412,7 +412,7 @@ namespace OpenSim.Framework.Servers.HttpServer // OpenSim.Framework.WebUtil.OSHeaderRequestID if (request.Headers["opensim-request-id"] != null) reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]); - // m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); + //m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl); Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true); @@ -440,7 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); -// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); + //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); if (TryGetStreamHandler(handlerKey, out requestHandler)) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs new file mode 100644 index 0000000..b570155 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs @@ -0,0 +1,111 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Server.Base; +using OpenSim.Server.Handlers.Base; +using OpenSim.Server.Handlers.MapImage; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MapImageServiceInConnectorModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static bool m_Enabled = false; + + private IConfigSource m_Config; + bool m_Registered = false; + + #region IRegionModule interface + + public void Initialise(IConfigSource config) + { + m_Config = config; + IConfig moduleConfig = config.Configs["Modules"]; + if (moduleConfig != null) + { + m_Enabled = moduleConfig.GetBoolean("MapImageServiceInConnector", false); + if (m_Enabled) + { + m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled"); + new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService"); + } + + } + + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "MapImageServiceIn"; } + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + } + + #endregion + + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs new file mode 100644 index 0000000..ee90859 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -0,0 +1,232 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Net; +using System.IO; +using System.Timers; +using System.Drawing; +using System.Drawing.Imaging; + +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage +{ + /// + /// + /// + /// + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MapImageServiceModule : ISharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_enabled = false; + private IMapImageService m_MapService; + + private string m_serverUrl = String.Empty; + private Dictionary m_scenes = new Dictionary(); + + private int m_refreshtime = 0; + private int m_lastrefresh = 0; + private System.Timers.Timer m_refreshTimer = new System.Timers.Timer(); + + #region ISharedRegionModule + + public Type ReplaceableInterface { get { return null; } } + public string Name { get { return "MapImageServiceModule"; } } + public void RegionLoaded(Scene scene) { } + public void Close() { } + public void PostInitialise() { } + + + /// + /// + /// + public void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("MapImageService", ""); + if (name != Name) + return; + } + + IConfig config = source.Configs["MapImageService"]; + if (config == null) + return; + + int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); + if (refreshminutes <= 0) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled."); + return; + } + + m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms + + string service = config.GetString("LocalServiceModule", string.Empty); + if (service == string.Empty) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No service dll given in config. Unable to proceed."); + return; + } + + Object[] args = new Object[] { source }; + m_MapService = ServerUtils.LoadPlugin(service, args); + + m_refreshTimer.Enabled = true; + m_refreshTimer.AutoReset = true; + m_refreshTimer.Interval = m_refreshtime; + m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); + + m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}", + refreshminutes, service); + + m_enabled = true; + } + + /// + /// + /// + + + /// + /// + /// + public void AddRegion(Scene scene) + { + if (! m_enabled) + return; + + // Every shared region module has to maintain an indepedent list of + // currently running regions + lock (m_scenes) + m_scenes[scene.RegionInfo.RegionID] = scene; + + scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); + } + + /// + /// + /// + public void RemoveRegion(Scene scene) + { + if (! m_enabled) + return; + + lock (m_scenes) + m_scenes.Remove(scene.RegionInfo.RegionID); + } + + #endregion ISharedRegionModule + + void EventManager_OnPrimsLoaded(Scene s) + { + UploadMapTile(s); + } + + + /// + /// + /// + private void HandleMaptileRefresh(object sender, EventArgs ea) + { + // this approach is a bit convoluted becase we want to wait for the + // first upload to happen on startup but after all the objects are + // loaded and initialized + if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime) + return; + + m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: map refresh!"); + lock (m_scenes) + { + foreach (IScene scene in m_scenes.Values) + { + try + { + UploadMapTile(scene); + } + catch (Exception ex) + { + m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: something bad happened {0}", ex.Message); + } + } + } + + m_lastrefresh = Util.EnvironmentTickCount(); + } + + /// + /// + /// + private void UploadMapTile(IScene scene) + { + m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName); + + // Create a PNG map tile and upload it to the AddMapTile API + byte[] jpgData = Utils.EmptyBytes; + IMapImageGenerator tileGenerator = scene.RequestModuleInterface(); + if (tileGenerator == null) + { + m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator"); + return; + } + + using (Image mapTile = tileGenerator.CreateMapTile()) + { + using (MemoryStream stream = new MemoryStream()) + { + mapTile.Save(stream, ImageFormat.Jpeg); + jpgData = stream.ToArray(); + } + } + + string reason = string.Empty; + if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason)) + { + m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}", + scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason); + } + + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 3553c9a..079b1c2 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -849,10 +849,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (minX - 4) * (int)Constants.RegionSize, - (maxX + 4) * (int)Constants.RegionSize, - (minY - 4) * (int)Constants.RegionSize, - (maxY + 4) * (int)Constants.RegionSize); + (minX - 8) * (int)Constants.RegionSize, + (maxX + 8) * (int)Constants.RegionSize, + (minY - 8) * (int)Constants.RegionSize, + (maxY + 8) * (int)Constants.RegionSize); foreach (GridRegion r in regions) { MapBlockData block = new MapBlockData(); diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs new file mode 100644 index 0000000..a953cd7 --- /dev/null +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -0,0 +1,61 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.MapImage +{ + public class MapAddServiceConnector : ServiceConnector + { + private IMapImageService m_MapService; + private string m_ConfigName = "MapImageService"; + + public MapAddServiceConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string gridService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (gridService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_MapService = ServerUtils.LoadPlugin(gridService, args); + + //server.AddStreamHandler(new PresenceServerPostHandler(m_PresenceService)); + } + } +} diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs new file mode 100644 index 0000000..9448af7 --- /dev/null +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -0,0 +1,105 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using log4net; + +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.MapImage +{ + public class MapGetServiceConnector : ServiceConnector + { + private IMapImageService m_MapService; + private string m_ConfigName = "MapImageService"; + + public MapGetServiceConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string gridService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (gridService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_MapService = ServerUtils.LoadPlugin(gridService, args); + + server.AddStreamHandler(new MapServerGetHandler(m_MapService)); + } + } + + class MapServerGetHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IMapImageService m_MapService; + + public MapServerGetHandler(IMapImageService service) : + base("GET", "/map") + { + m_MapService = service; + } + + public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: retrieving {0}", path); + byte[] result = new byte[0]; + + string format = string.Empty; + result = m_MapService.GetMapTile(path.Trim('/'), out format); + + if (result.Length > 0) + { + httpResponse.StatusCode = (int)HttpStatusCode.OK; + if (format.Equals("png")) + httpResponse.ContentType = "image/png"; + else if (format.Equals("jpg") || format.Equals("jpeg")) + httpResponse.ContentType = "image/jpeg"; + } + else + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + httpResponse.ContentType = "text/plain"; + } + + return result; + } + + } +} diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs new file mode 100644 index 0000000..ff0e9d9 --- /dev/null +++ b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs @@ -0,0 +1,158 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; +using OpenSim.Services.Interfaces; +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Services.Connectors +{ + public class MapImageServicesConnector : IMapImageService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + private IImprovedAssetCache m_Cache = null; + + public MapImageServicesConnector() + { + } + + public MapImageServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public MapImageServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig config = source.Configs["MapImageService"]; + if (config == null) + { + m_log.Error("[MAP IMAGE CONNECTOR]: MapImageService missing"); + throw new Exception("MapImage connector init error"); + } + + string serviceURI = config.GetString("MapImageServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[MAP IMAGE CONNECTOR]: No Server URI named in section MapImageService"); + throw new Exception("MapImage connector init error"); + } + m_ServerURI = serviceURI; + } + + public bool AddMapTile(int x, int y, byte[] pngData, out string reason) + { + List postParameters = new List() + { + new MultipartForm.Parameter("X", x.ToString()), + new MultipartForm.Parameter("Y", y.ToString()), + new MultipartForm.File("Tile", "tile.png", "image/png", pngData) + }; + + reason = string.Empty; + int tickstart = Util.EnvironmentTickCount(); + + // Make the remote storage request + try + { + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI); + request.Timeout = 20000; + request.ReadWriteTimeout = 5000; + + using (HttpWebResponse response = MultipartForm.Post(request, postParameters)) + { + using (Stream responseStream = response.GetResponseStream()) + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + { + OSDMap responseMap = (OSDMap)responseOSD; + if (responseMap["Success"].AsBoolean()) + return true; + + reason = "Upload failed: " + responseMap["Message"].AsString(); + } + else + { + reason = "Response format was invalid:\n" + responseStr; + } + } + } + } + catch (WebException we) + { + reason = we.Message; + if (we.Status == WebExceptionStatus.ProtocolError) + { + HttpWebResponse webResponse = (HttpWebResponse)we.Response; + reason = String.Format("[{0}] {1}", webResponse.StatusCode, webResponse.StatusDescription); + } + } + catch (Exception ex) + { + reason = ex.Message; + } + finally + { + // This just dumps a warning for any operation that takes more than 100 ms + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff); + } + + return false; + } + + public byte[] GetMapTile(string fileName, out string format) + { + format = string.Empty; + new Exception("GetMapTile method not Implemented"); + return null; + } + } +} diff --git a/OpenSim/Services/Interfaces/IMapImageService.cs b/OpenSim/Services/Interfaces/IMapImageService.cs new file mode 100644 index 0000000..a7b2cf1 --- /dev/null +++ b/OpenSim/Services/Interfaces/IMapImageService.cs @@ -0,0 +1,40 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Framework; +using System.Collections.Generic; +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IMapImageService + { + //List GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY); + bool AddMapTile(int x, int y, byte[] imageData, out string reason); + byte[] GetMapTile(string fileName, out string format); + } +} diff --git a/OpenSim/Services/Interfaces/IMapService.cs b/OpenSim/Services/Interfaces/IMapService.cs deleted file mode 100644 index c70f484..0000000 --- a/OpenSim/Services/Interfaces/IMapService.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using OpenSim.Framework; -using System.Collections.Generic; -using OpenMetaverse; - -namespace OpenSim.Services.Interfaces -{ - public interface IMapService - { - List GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY); - } -} diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs new file mode 100644 index 0000000..596c4a6 --- /dev/null +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -0,0 +1,295 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Net; +using System.Reflection; + +using Nini.Config; +using log4net; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Services.Interfaces; + + +namespace OpenSim.Services.MapImageService +{ + public class MapImageService : IMapImageService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private const int ZOOM_LEVELS = 8; + private const int IMAGE_WIDTH = 256; + private const int HALF_WIDTH = 128; + private const int JPEG_QUALITY = 80; + + private static string m_TilesStoragePath = "maptiles"; + + private static object m_Sync = new object(); + private static bool m_Initialized = false; + private static string m_WaterTileFile = string.Empty; + private static Color m_Watercolor = Color.FromArgb(29, 71, 95); + + public MapImageService(IConfigSource config) + { + if (!m_Initialized) + { + m_Initialized = true; + m_log.Debug("[MAP IMAGE SERVICE]: Starting MapImage service"); + + IConfig serviceConfig = config.Configs["MapImageService"]; + if (serviceConfig != null) + { + m_TilesStoragePath = serviceConfig.GetString("TilesStoragePath", m_TilesStoragePath); + if (!Directory.Exists(m_TilesStoragePath)) + Directory.CreateDirectory(m_TilesStoragePath); + + + m_WaterTileFile = Path.Combine(m_TilesStoragePath, "water.jpg"); + if (!File.Exists(m_WaterTileFile)) + { + Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); + FillImage(waterTile, m_Watercolor); + waterTile.Save(m_WaterTileFile); + } + } + } + } + + #region IMapImageService + + public bool AddMapTile(int x, int y, byte[] imageData, out string reason) + { + reason = string.Empty; + string fileName = GetFileName(1, x, y); + + lock (m_Sync) + { + try + { + using (FileStream f = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write)) + f.Write(imageData, 0, imageData.Length); + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save image file {0}: {1}", fileName, e); + reason = e.Message; + return false; + } + + // Also save in png format? + + // Stitch seven more aggregate tiles together + for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) + { + // Calculate the width (in full resolution tiles) and bottom-left + // corner of the current zoom level + int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); + int x1 = x - (x % width); + int y1 = y - (y % width); + + if (!CreateTile(zoomLevel, x1, y1)) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0} at zoom level {1}", fileName, zoomLevel); + reason = string.Format("Map tile at zoom level {0} failed", zoomLevel); + return false; + } + } + } + + return true; + } + + public byte[] GetMapTile(string fileName, out string format) + { + format = "jpg"; + string fullName = Path.Combine(m_TilesStoragePath, fileName); + if (File.Exists(fullName)) + { + format = Path.GetExtension(fileName).ToLower(); + m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format); + return File.ReadAllBytes(fullName); + } + else if (File.Exists(m_WaterTileFile)) + { + m_log.DebugFormat("[MAP IMAGE SERVICE]: File not found {0}, sending water", fileName); + return File.ReadAllBytes(m_WaterTileFile); + } + else + { + m_log.DebugFormat("[MAP IMAGE SERVICE]: unable to get file {0}", fileName); + return new byte[0]; + } + } + + #endregion + + + private string GetFileName(uint zoomLevel, int x, int y) + { + string extension = "jpg"; + return Path.Combine(m_TilesStoragePath, string.Format("map-{0}-{1}-{2}-objects.{3}", zoomLevel, x, y, extension)); + } + + private Bitmap GetInputTileImage(string fileName) + { + try + { + if (File.Exists(fileName)) + return new Bitmap(fileName); + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e); + } + + return null; + } + + private Bitmap GetOutputTileImage(string fileName) + { + try + { + if (File.Exists(fileName)) + return new Bitmap(fileName); + + else + { + // Create a new output tile with a transparent background + Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); + bm.MakeTransparent(); + return bm; + } + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e); + } + + return null; + } + + private bool CreateTile(uint zoomLevel, int x, int y) + { + m_log.DebugFormat("[MAP IMAGE SERVICE]: Create tile for {0} {1}, zoom {2}", x, y, zoomLevel); + int prevWidth = (int)Math.Pow(2, (double)zoomLevel - 2); + int thisWidth = (int)Math.Pow(2, (double)zoomLevel - 1); + + // Convert x and y to the bottom left tile for this zoom level + int xIn = x - (x % prevWidth); + int yIn = y - (y % prevWidth); + + // Convert x and y to the bottom left tile for the next zoom level + int xOut = x - (x % thisWidth); + int yOut = y - (y % thisWidth); + + // Try to open the four input tiles from the previous zoom level + Bitmap inputBL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn)); + Bitmap inputBR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn)); + Bitmap inputTL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn + prevWidth)); + Bitmap inputTR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn + prevWidth)); + + // Open the output tile (current zoom level) + string outputFile = GetFileName(zoomLevel, xOut, yOut); + Bitmap output = GetOutputTileImage(outputFile); + if (output == null) + return false; + FillImage(output, m_Watercolor); + + if (inputBL != null) + { + ImageCopyResampled(output, inputBL, 0, HALF_WIDTH, 0, 0); + inputBL.Dispose(); + } + if (inputBR != null) + { + ImageCopyResampled(output, inputBR, HALF_WIDTH, HALF_WIDTH, 0, 0); + inputBR.Dispose(); + } + if (inputTL != null) + { + ImageCopyResampled(output, inputTL, 0, 0, 0, 0); + inputTL.Dispose(); + } + if (inputTR != null) + { + ImageCopyResampled(output, inputTR, HALF_WIDTH, 0, 0, 0); + inputTR.Dispose(); + } + + // Write the modified output + try + { + using (Bitmap final = new Bitmap(output)) + { + output.Dispose(); + final.Save(outputFile); + } + } + catch (Exception e) + { + m_log.WarnFormat("[MAP IMAGE SERVICE]: Oops on saving {0} {1}", outputFile, e); + } + + // Save also as png? + + return true; + } + + #region Image utilities + + private void FillImage(Bitmap bm, Color c) + { + for (int x = 0; x < bm.Width; x++) + for (int y = 0; y < bm.Height; y++) + bm.SetPixel(x, y, c); + } + + private void ImageCopyResampled(Bitmap output, Bitmap input, int destX, int destY, int srcX, int srcY) + { + int resamplingRateX = 2; // (input.Width - srcX) / (output.Width - destX); + int resamplingRateY = 2; // (input.Height - srcY) / (output.Height - destY); + + for (int x = destX; x < destX + HALF_WIDTH; x++) + for (int y = destY; y < destY + HALF_WIDTH; y++) + { + Color p = input.GetPixel(srcX + (x - destX) * resamplingRateX, srcY + (y - destY) * resamplingRateY); + output.SetPixel(x, y, p); + } + } + + #endregion + } +} diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 4ff1a26..bf89d0b 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -17,10 +17,12 @@ AvatarServices = "LocalAvatarServicesConnector" EntityTransferModule = "BasicEntityTransferModule" InventoryAccessModule = "BasicInventoryAccessModule" + MapImageService = "MapImageServiceModule" LibraryModule = true LLLoginServiceInConnector = true GridInfoServiceInConnector = true + MapImageServiceInConnector = true [Profile] Module = "BasicProfileModule" @@ -91,6 +93,11 @@ WelcomeMessage = "Welcome, Avatar!" +[MapImageService] + LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + ; in minutes + RefreshTime = 60 + ;; This should always be the very last thing on this file [Includes] Include-Common = "config-include/StandaloneCommon.ini" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 7359bba..69349d2 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -99,6 +99,9 @@ SRV_FriendsServerURI = "http://127.0.0.1:9000" SRV_IMServerURI = "http://127.0.0.1:9000" + ;; For Viewer 2 + MapTileURL = "http://127.0.0.1:9000" + ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. ;; diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 8480a77..719df5c 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -18,9 +18,10 @@ GridUserServices = "LocalGridUserServicesConnector" SimulationServices = "RemoteSimulationConnectorModule" AvatarServices = "LocalAvatarServicesConnector" + MapImageService = "MapImageServiceModule" EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" - FriendsModule = "HGFriendsModule" + FriendsModule = "HGFriendsModule" InventoryServiceInConnector = true AssetServiceInConnector = true @@ -31,6 +32,7 @@ GridInfoServiceInConnector = true AuthenticationServiceInConnector = true SimulationServiceInConnector = true + MapImageServiceInConnector = true [Profile] Module = "BasicProfileModule" @@ -116,7 +118,12 @@ GridService = "OpenSim.Services.GridService.dll:GridService" AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" - + +[MapImageService] + LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" + ; in minutes + RefreshTime = 60 + [GatekeeperService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:GatekeeperService" ;; for the service diff --git a/prebuild.xml b/prebuild.xml index 90f451d..ed79b40 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1269,6 +1269,36 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + -- cgit v1.1 From 78c16da5444a2e363de50bc88c8d2b929dec0989 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 17:05:45 -0700 Subject: A few bug fixes on map V2. Zoom level weirdness still there. --- .../CoreModules/World/WorldMap/WorldMapModule.cs | 18 ++++++++++++------ OpenSim/Server/Handlers/Map/MapGetServerConnector.cs | 5 ++--- OpenSim/Services/MapImageService/MapImageService.cs | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 079b1c2..6e142bb 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -836,7 +836,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap block.Access = 254; // means 'simulator is offline' response.Add(block); } - remoteClient.SendMapBlock(response, 0); + if ((flag & 2) == 2) // V2 !!! + remoteClient.SendMapBlock(response, 2); + else + remoteClient.SendMapBlock(response, 0); } else { @@ -849,17 +852,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { List mapBlocks = new List(); List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (minX - 8) * (int)Constants.RegionSize, - (maxX + 8) * (int)Constants.RegionSize, - (minY - 8) * (int)Constants.RegionSize, - (maxY + 8) * (int)Constants.RegionSize); + (minX - 4) * (int)Constants.RegionSize, + (maxX + 4) * (int)Constants.RegionSize, + (minY - 4) * (int)Constants.RegionSize, + (maxY + 4) * (int)Constants.RegionSize); foreach (GridRegion r in regions) { MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r); mapBlocks.Add(block); } - remoteClient.SendMapBlock(mapBlocks, 0); + if ((flag & 2) == 2) // V2 !!! + remoteClient.SendMapBlock(mapBlocks, 2); + else + remoteClient.SendMapBlock(mapBlocks, 0); return mapBlocks; } diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index 9448af7..76dd695 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -83,13 +83,12 @@ namespace OpenSim.Server.Handlers.MapImage string format = string.Empty; result = m_MapService.GetMapTile(path.Trim('/'), out format); - if (result.Length > 0) { httpResponse.StatusCode = (int)HttpStatusCode.OK; - if (format.Equals("png")) + if (format.Equals(".png")) httpResponse.ContentType = "image/png"; - else if (format.Equals("jpg") || format.Equals("jpeg")) + else if (format.Equals(".jpg") || format.Equals(".jpeg")) httpResponse.ContentType = "image/jpeg"; } else diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index 596c4a6..ee424e1 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -134,7 +134,7 @@ namespace OpenSim.Services.MapImageService public byte[] GetMapTile(string fileName, out string format) { - format = "jpg"; + format = ".jpg"; string fullName = Path.Combine(m_TilesStoragePath, fileName); if (File.Exists(fullName)) { -- cgit v1.1 From 07d7c1cd2d0d5ccf6d40a3616ecaeb565e9bfab4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 18:29:44 -0700 Subject: Trailing / in MapTileURL must be there! --- bin/config-include/StandaloneCommon.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 69349d2..29c2af1 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -100,7 +100,7 @@ SRV_IMServerURI = "http://127.0.0.1:9000" ;; For Viewer 2 - MapTileURL = "http://127.0.0.1:9000" + MapTileURL = "http://127.0.0.1:9000/" ;; Regular expressions for controlling which client versions are accepted/denied. ;; An empty string means nothing is checked. -- cgit v1.1 From 2e77518c6dd5f06c965df758ebd0a20a39c96dc8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 21:51:26 -0700 Subject: bit depth: 24!!! begeez! -- zoom levels work now. --- OpenSim/Server/Handlers/Map/MapGetServerConnector.cs | 4 +++- OpenSim/Services/MapImageService/MapImageService.cs | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index 76dd695..53d08fa 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -42,11 +42,13 @@ namespace OpenSim.Server.Handlers.MapImage { public class MapGetServiceConnector : ServiceConnector { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IMapImageService m_MapService; + private string m_ConfigName = "MapImageService"; public MapGetServiceConnector(IConfigSource config, IHttpServer server, string configName) : - base(config, server, configName) + base(config, server, configName) { IConfig serverConfig = config.Configs[m_ConfigName]; if (serverConfig == null) diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index ee424e1..736fa2e 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -144,7 +144,6 @@ namespace OpenSim.Services.MapImageService } else if (File.Exists(m_WaterTileFile)) { - m_log.DebugFormat("[MAP IMAGE SERVICE]: File not found {0}, sending water", fileName); return File.ReadAllBytes(m_WaterTileFile); } else @@ -188,7 +187,7 @@ namespace OpenSim.Services.MapImageService else { // Create a new output tile with a transparent background - Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); + Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH, PixelFormat.Format24bppRgb); bm.MakeTransparent(); return bm; } @@ -255,7 +254,7 @@ namespace OpenSim.Services.MapImageService using (Bitmap final = new Bitmap(output)) { output.Dispose(); - final.Save(outputFile); + final.Save(outputFile, ImageFormat.Jpeg); } } catch (Exception e) -- cgit v1.1 From 95e050130c42c21ca4f26b31abce1c4a83194525 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 22:10:16 -0700 Subject: People are bound to forget the '/' at the end of MapTileURL, so let's correct that from the inside. --- OpenSim/Services/LLLoginService/LLLoginService.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 5d1779a..2b15896 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -112,6 +112,14 @@ namespace OpenSim.Services.LLLoginService m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); + // Clean up some of these vars + if (m_MapTileURL != String.Empty) + { + m_MapTileURL = m_MapTileURL.Trim(); + if (!m_MapTileURL.EndsWith("/")) + m_MapTileURL = m_MapTileURL + "/"; + } + // These are required; the others aren't if (accountService == string.Empty || authService == string.Empty) throw new Exception("LoginService is missing service specifications"); -- cgit v1.1 From 4b9de140ab9aa9312219610de68138c4288b840a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 12 Jun 2011 22:25:30 -0700 Subject: Add credit and link to SimianGrid project. Thanks, guys! --- OpenSim/Services/MapImageService/MapImageService.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index 736fa2e..27722bb 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs @@ -23,6 +23,10 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The design of this map service is based on SimianGrid's PHP-based + * map service. See this URL for the original PHP version: + * https://github.com/openmetaversefoundation/simiangrid/ */ using System; -- cgit v1.1 From dc978d02a723440a3860da0ad6a2b61b09769f39 Mon Sep 17 00:00:00 2001 From: Michael Cerquoni aka Nebadon Izumi Date: Mon, 13 Jun 2011 03:46:24 -0700 Subject: match water color for warp3d map tiler and adjust lighting --- OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs index 6eb57eb..6163fd1 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs @@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule { private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); - private static readonly Color4 WATER_COLOR = new Color4(29, 71, 95, 216); + private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private IRendering m_primMesher; private IConfigSource m_config; private Dictionary m_colors = new Dictionary(); - private bool m_useAntiAliasing = true; // TODO: Make this a config option + private bool m_useAntiAliasing = false; // TODO: Make this a config option private bool m_Enabled = false; #region IRegionModule Members @@ -192,8 +192,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap #endregion Camera - renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0.2f, 0.2f, 1f), 0xffffff, 320, 80)); - renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 100, 40)); + renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40)); + renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40)); CreateWater(renderer); CreateTerrain(renderer, textureTerrain); @@ -237,6 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f); renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR)); + renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); renderer.SetObjectMaterial("Water", "WaterColor"); } @@ -322,6 +323,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap warp_Material material = new warp_Material(texture); material.setReflectivity(50); renderer.Scene.addMaterial("TerrainColor", material); + renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif renderer.SetObjectMaterial("Terrain", "TerrainColor"); } @@ -653,4 +655,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap return result; } } -} +} \ No newline at end of file -- cgit v1.1