diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs index c2b004604d..2bfcaca77f 100644 --- a/OpenSim/Framework/Communications/Capabilities/Caps.cs +++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs @@ -135,10 +135,10 @@ namespace OpenSim.Framework.Communications.Capabilities { // the root of all evil m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest); - m_capsHandlers["MapLayer"] = - new LLSDStreamhandler("POST", - capsBase + m_mapLayerPath, - GetMapLayer); + //m_capsHandlers["MapLayer"] = + // new LLSDStreamhandler("POST", + // capsBase + m_mapLayerPath, + // GetMapLayer); m_capsHandlers["NewFileAgentInventory"] = new LLSDStreamhandler("POST", capsBase + m_newInventory, @@ -420,6 +420,7 @@ namespace OpenSim.Framework.Communications.Capabilities mapLayer.Right = 5000; mapLayer.Top = 5000; mapLayer.ImageID = new LLUUID("00000000-0000-1111-9999-000000000006"); + return mapLayer; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 47a9f53b7a..5cbe04ee45 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -1209,29 +1209,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(newSimPack, ThrottleOutPacketType.Unknown); } - public void SendMapBlock(List mapBlocks) + internal void SendMapBlockSplit(List mapBlocks) { MapBlockReplyPacket mapReply = (MapBlockReplyPacket)PacketPool.Instance.GetPacket(PacketType.MapBlockReply); // TODO: don't create new blocks if recycling an old packet + + MapBlockData[] mapBlocks2 = mapBlocks.ToArray(); + mapReply.AgentData.AgentID = AgentId; - mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count]; + mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks2.Length]; mapReply.AgentData.Flags = 0; - for (int i = 0; i < mapBlocks.Count; i++) + for (int i = 0; i < mapBlocks2.Length; i++) { mapReply.Data[i] = new MapBlockReplyPacket.DataBlock(); - mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId; - mapReply.Data[i].X = mapBlocks[i].X; - mapReply.Data[i].Y = mapBlocks[i].Y; - mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight; - mapReply.Data[i].Name = Helpers.StringToField(mapBlocks[i].Name); - mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags; - mapReply.Data[i].Access = mapBlocks[i].Access; - mapReply.Data[i].Agents = mapBlocks[i].Agents; + mapReply.Data[i].MapImageID = mapBlocks2[i].MapImageId; + mapReply.Data[i].X = mapBlocks2[i].X; + mapReply.Data[i].Y = mapBlocks2[i].Y; + mapReply.Data[i].WaterHeight = mapBlocks2[i].WaterHeight; + mapReply.Data[i].Name = Helpers.StringToField(mapBlocks2[i].Name); + mapReply.Data[i].RegionFlags = mapBlocks2[i].RegionFlags; + mapReply.Data[i].Access = mapBlocks2[i].Access; + mapReply.Data[i].Agents = mapBlocks2[i].Agents; } OutPacket(mapReply, ThrottleOutPacketType.Land); } + public void SendMapBlock(List mapBlocks) + { + + MapBlockData[] mapBlocks2 = mapBlocks.ToArray(); + + int maxsend = 10; + + //int packets = Math.Ceiling(mapBlocks2.Length / maxsend); + + List sendingBlocks = new List(); + + for (int i = 0; i < mapBlocks2.Length; i++) + { + sendingBlocks.Add(mapBlocks2[i]); + if (((i + 1) == mapBlocks2.Length) || ((i % maxsend) == 0)) + { + SendMapBlockSplit(sendingBlocks); + sendingBlocks = new List(); + } + } + } + public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags) { TeleportLocalPacket tpLocal = (TeleportLocalPacket)PacketPool.Instance.GetPacket(PacketType.TeleportLocal); diff --git a/OpenSim/Region/Environment/Modules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/Environment/Modules/World/WorldMap/WorldMapModule.cs new file mode 100644 index 0000000000..041af2b6a5 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/World/WorldMap/WorldMapModule.cs @@ -0,0 +1,239 @@ +/* + * 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 OpenSim 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; +using System.Collections.Generic; +using System.Reflection; +using libsecondlife; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; +using OpenSim.Framework.Communications.Capabilities; +using OpenSim.Framework.Servers; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.Types; +using Caps = OpenSim.Framework.Communications.Capabilities.Caps; + + +namespace OpenSim.Region.Environment.Modules.World.WorldMap +{ + public class WorldMapModule : IRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly string m_mapLayerPath = "0001/"; + + //private IConfig m_config; + private Scene m_scene; + private List cachedMapBlocks = new List(); + private int cachedTime = 0; + + //private int CacheRegionsDistance = 256; + + #region IRegionModule Members + + public void Initialise(Scene scene, IConfigSource config) + { + m_scene = scene; + + //QuadTree.Subdivide(); + //QuadTree.Subdivide(); + + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += ClientLoggedOut; + } + public void PostInitialise() + { + + } + + public void Close() + { + } + public string Name + { + get { return "WorldMapModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + #endregion + + + + + + public void OnRegisterCaps(LLUUID agentID, Caps caps) + { + m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); + string capsBase = "/CAPS/" + caps.CapsObjectPath; + caps.RegisterHandler("MapLayer", + new RestStreamHandler("POST", capsBase + m_mapLayerPath, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return MapLayerRequest(request, path, param, + agentID, caps); + })); + + } + + /// + /// Callback for a map layer request + /// + /// + /// + /// + /// + /// + /// + public string MapLayerRequest(string request, string path, string param, + LLUUID agentID, Caps caps) + { + //try + //{ + //m_log.DebugFormat("[MAPLAYER]: request: {0}, path: {1}, param: {2}, agent:{3}", + //request, path, param,agentID.ToString()); + + // this is here because CAPS map requests work even beyond the 10,000 limit. + ScenePresence avatarPresence = null; + + m_scene.TryGetAvatar(agentID, out avatarPresence); + + if (avatarPresence != null) + { + bool lookup = false; + + lock(cachedMapBlocks) + { + if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) + { + List mapBlocks; + + mapBlocks = cachedMapBlocks; + avatarPresence.ControllingClient.SendMapBlock(mapBlocks); + } + else + { + lookup = true; + } + } + if (lookup) + { + List mapBlocks; + + mapBlocks = m_scene.CommsManager.GridService.RequestNeighbourMapBlocks((int)m_scene.RegionInfo.RegionLocX - 8, (int)m_scene.RegionInfo.RegionLocY - 8, (int)m_scene.RegionInfo.RegionLocX + 8, (int)m_scene.RegionInfo.RegionLocY + 8); + avatarPresence.ControllingClient.SendMapBlock(mapBlocks); + + lock(cachedMapBlocks) + cachedMapBlocks = mapBlocks; + + cachedTime = Util.UnixTimeSinceEpoch(); + } + } + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); + mapResponse.LayerData.Array.Add(GetLLSDMapLayerResponse()); + return mapResponse.ToString(); + } + + /// + /// + /// + /// + /// + public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) + { + m_log.Debug("[CAPS]: MapLayer Request in region: " + m_scene.RegionInfo.RegionName); + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); + mapResponse.LayerData.Array.Add(GetLLSDMapLayerResponse()); + return mapResponse; + } + + /// + /// + /// + /// + protected static LLSDMapLayer GetLLSDMapLayerResponse() + { + LLSDMapLayer mapLayer = new LLSDMapLayer(); + mapLayer.Right = 5000; + mapLayer.Top = 5000; + mapLayer.ImageID = new LLUUID("00000000-0000-1111-9999-000000000006"); + + return mapLayer; + } + #region EventHandlers + + + private void OnNewClient(IClientAPI client) + { + // All friends establishment protocol goes over instant message + // There's no way to send a message from the sim + // to a user to 'add a friend' without causing dialog box spam + // + // The base set of friends are added when the user signs on in their XMLRPC response + // Generated by LoginService. The friends are retreived from the database by the UserManager + + // Subscribe to instant messages + + //client.OnInstantMessage += OnInstantMessage; + //client.OnApproveFriendRequest += OnApprovedFriendRequest; + //client.OnDenyFriendRequest += OnDenyFriendRequest; + //client.OnTerminateFriendship += OnTerminateFriendship; + + //doFriendListUpdateOnline(client.AgentId); + client.OnRequestMapBlocks += RequestMapBlocks; + } + private void ClientLoggedOut(LLUUID AgentId) + { + + } + #endregion + + /// + /// Requests map blocks in area of minX, maxX, minY, MaxY in world cordinates + /// + /// + /// + /// + /// + public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) + { + List mapBlocks; + mapBlocks = m_scene.CommsManager.GridService.RequestNeighbourMapBlocks(minX - 4, minY - 4, minX + 4, minY + 4); + remoteClient.SendMapBlock(mapBlocks); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 43bb709371..95d6f1ff7e 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1867,7 +1867,7 @@ namespace OpenSim.Region.Environment.Scenes client.OnUpdatePrimGroupScale += m_innerScene.UpdatePrimGroupScale; client.OnUpdateExtraParams += m_innerScene.UpdateExtraParam; client.OnUpdatePrimShape += m_innerScene.UpdatePrimShape; - client.OnRequestMapBlocks += RequestMapBlocks; + //client.OnRequestMapBlocks += RequestMapBlocks; // handled in a module now. client.OnUpdatePrimTexture += m_innerScene.UpdatePrimTexture; client.OnTeleportLocationRequest += RequestTeleportLocation; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; @@ -2487,7 +2487,8 @@ namespace OpenSim.Region.Environment.Scenes /// public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) { - m_sceneGridService.RequestMapBlocks(remoteClient, minX, minY, maxX, maxX); + m_log.InfoFormat("[MAPBLOCK]: {0}-{1}, {2}-{3}", minX, minY, maxX, maxY); + m_sceneGridService.RequestMapBlocks(remoteClient, minX, minY, maxX, maxY); } /// diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 300a363569..2774a45d9c 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -81,7 +81,7 @@ namespace OpenSim.Region.Environment.Scenes private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; private SceneObjectGroup proxyObjectGroup = null; - private SceneObjectPart proxyObjectPart = null; + //private SceneObjectPart proxyObjectPart = null; public Vector3 lastKnownAllowedPosition = new Vector3(); public bool sentMessageAboutRestrictedParcelFlyingDown = false;