Mantis#1965. Thank you kindly, HomerHorwitz for a patch that:

Places touched:
- Added two events for in-packets to LLCLientView: RegionHandleRequest and
  ParcelInfoRequest
- Added sending of two out-packets to LLCLientView: RegionIDAndHandleReply and
  ParcelInfoReply.
- Scene handles the RegionHandleRequest, LandManagementModule the
  ParcelInfoRequest
- Added inter-region request for LandData by RegionHandle and local position.
  This was implemented as XML-RPC request. The returned LandData isn't
  complete, it only contains the data necessary for answering the
  ParcelInfoRequest
- Added new CAPS (0009) for RemoteParcelRequest and some methods for LandData
  handling to LandManagementModule
- Added methods for fake parcelID creation and parsing to Util
- Fixed missing implementation of interface methods.
- Added new file:
    OpenSim/Framework/Communications/Capabilities/LLSDRemoteParcelResponse.cs
  NOTE: This is part of the patch, too.
Due to the many places touched, I would consider this patch as experimental.
0.6.0-stable
Charles Krinke 2008-08-16 19:20:14 +00:00
parent f191f38a3e
commit d9cc908471
15 changed files with 448 additions and 6 deletions

View File

@ -86,11 +86,13 @@ namespace OpenSim.Framework.Communications.Capabilities
private static readonly string m_notecardTaskUpdatePath = "0005/"; private static readonly string m_notecardTaskUpdatePath = "0005/";
// private static readonly string m_fetchInventoryPath = "0006/"; // private static readonly string m_fetchInventoryPath = "0006/";
// The following two entries are in a module, however, there also here so that we don't re-assign // The following entries are in a module, however, they are also here so that we don't re-assign
// the path to another cap by mistake. // the path to another cap by mistake.
// private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module. // private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module.
// private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module. // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module.
// private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
//private string eventQueue = "0100/"; //private string eventQueue = "0100/";
private BaseHttpServer m_httpListener; private BaseHttpServer m_httpListener;
private LLUUID m_agentID; private LLUUID m_agentID;

View File

@ -0,0 +1,42 @@
/*
* 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 libsecondlife;
namespace OpenSim.Framework.Communications.Capabilities
{
[LLSDType("MAP")]
public class LLSDRemoteParcelResponse
{
public LLUUID parcel_id;
public LLSDRemoteParcelResponse()
{
}
}
}

View File

@ -57,5 +57,7 @@ namespace OpenSim.Framework.Communications
RegionInfo RequestClosestRegion(string regionName); RegionInfo RequestClosestRegion(string regionName);
Dictionary<string, string> GetGridSettings(); Dictionary<string, string> GetGridSettings();
List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY); List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY);
// not complete yet, only contains the fields needed for ParcelInfoReqeust
LandData RequestLandData(ulong regionHandle, uint x, uint y);
} }
} }

View File

@ -293,6 +293,9 @@ namespace OpenSim.Framework
public delegate void EstateBlueBoxMessageRequest(IClientAPI remoteClient, LLUUID invoice, LLUUID senderID, LLUUID sessionID, string senderName, string message); public delegate void EstateBlueBoxMessageRequest(IClientAPI remoteClient, LLUUID invoice, LLUUID senderID, LLUUID sessionID, string senderName, string message);
public delegate void EstateDebugRegionRequest(IClientAPI remoteClient, LLUUID invoice, LLUUID senderID, bool scripted, bool collisionEvents, bool physics); public delegate void EstateDebugRegionRequest(IClientAPI remoteClient, LLUUID invoice, LLUUID senderID, bool scripted, bool collisionEvents, bool physics);
public delegate void EstateTeleportOneUserHomeRequest(IClientAPI remoteClient, LLUUID invoice, LLUUID senderID, LLUUID prey); public delegate void EstateTeleportOneUserHomeRequest(IClientAPI remoteClient, LLUUID invoice, LLUUID senderID, LLUUID prey);
public delegate void RegionHandleRequest(IClientAPI remoteClient, LLUUID regionID);
public delegate void ParcelInfoRequest(IClientAPI remoteClient, LLUUID parcelID);
public delegate void ScriptReset(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID); public delegate void ScriptReset(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID);
public delegate void GetScriptRunning(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID); public delegate void GetScriptRunning(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID);
public delegate void SetScriptRunning(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID, bool running); public delegate void SetScriptRunning(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID, bool running);
@ -498,6 +501,9 @@ namespace OpenSim.Framework
event EstateDebugRegionRequest OnEstateDebugRegionRequest; event EstateDebugRegionRequest OnEstateDebugRegionRequest;
event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest; event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
event UUIDNameRequest OnUUIDGroupNameRequest; event UUIDNameRequest OnUUIDGroupNameRequest;
event RegionHandleRequest OnRegionHandleRequest;
event ParcelInfoRequest OnParcelInfoRequest;
event RequestObjectPropertiesFamily OnObjectGroupRequest; event RequestObjectPropertiesFamily OnObjectGroupRequest;
event ScriptReset OnScriptReset; event ScriptReset OnScriptReset;
@ -721,5 +727,8 @@ namespace OpenSim.Framework
void SendSetFollowCamProperties(LLUUID objectID, SortedDictionary<int, float> parameters); void SendSetFollowCamProperties(LLUUID objectID, SortedDictionary<int, float> parameters);
void SendClearFollowCamProperties(LLUUID objectID); void SendClearFollowCamProperties(LLUUID objectID);
void SendRegionHandle(LLUUID regoinID, ulong handle);
void SendParcelInfo(RegionInfo info, LandData land, LLUUID parcelID, uint x, uint y);
} }
} }

View File

@ -52,6 +52,8 @@ namespace OpenSim.Framework
public delegate void LogOffUser(ulong regionHandle, LLUUID agentID, LLUUID regionSecret, string message); public delegate void LogOffUser(ulong regionHandle, LLUUID agentID, LLUUID regionSecret, string message);
public delegate LandData GetLandData(uint x, uint y);
public interface IRegionCommsListener public interface IRegionCommsListener
{ {
event ExpectUserDelegate OnExpectUser; event ExpectUserDelegate OnExpectUser;
@ -66,5 +68,6 @@ namespace OpenSim.Framework
event RegionUp OnRegionUp; event RegionUp OnRegionUp;
event ChildAgentUpdate OnChildAgentUpdate; event ChildAgentUpdate OnChildAgentUpdate;
event LogOffUser OnLogOffUser; event LogOffUser OnLogOffUser;
event GetLandData OnGetLandData;
} }
} }

View File

@ -46,7 +46,8 @@ namespace OpenSim.Framework
private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion;
private RegionUp handlerRegionUp = null; // OnRegionUp; private RegionUp handlerRegionUp = null; // OnRegionUp;
private LogOffUser handlerLogOffUser = null; private LogOffUser handlerLogOffUser = null;
private GetLandData handlerGetLandData = null;
#region IRegionCommsListener Members #region IRegionCommsListener Members
public event ExpectUserDelegate OnExpectUser; public event ExpectUserDelegate OnExpectUser;
@ -61,6 +62,7 @@ namespace OpenSim.Framework
public event RegionUp OnRegionUp; public event RegionUp OnRegionUp;
public event ChildAgentUpdate OnChildAgentUpdate; public event ChildAgentUpdate OnChildAgentUpdate;
public event LogOffUser OnLogOffUser; public event LogOffUser OnLogOffUser;
public event GetLandData OnGetLandData;
#endregion #endregion
@ -226,5 +228,14 @@ namespace OpenSim.Framework
return false; return false;
} }
public LandData TriggerGetLandData(uint x, uint y)
{
handlerGetLandData = OnGetLandData;
if (handlerGetLandData != null)
return handlerGetLandData(x, y);
return null;
}
} }
} }

View File

@ -716,5 +716,24 @@ namespace OpenSim.Framework
XmlRpcRequest client = new XmlRpcRequest(methodName, args); XmlRpcRequest client = new XmlRpcRequest(methodName, args);
return client.Send(url, 6000); return client.Send(url, 6000);
} }
// used for RemoteParcelRequest (for "About Landmark")
public static LLUUID BuildFakeParcelID(ulong regionHandle, uint x, uint y) {
byte[] bytes = {
(byte)(regionHandle >> 56), (byte)(regionHandle >> 48), (byte)(regionHandle >> 40), (byte)(regionHandle >> 32),
(byte)(regionHandle >> 24), (byte)(regionHandle >> 16), (byte)(regionHandle >> 8), (byte)regionHandle,
(byte)(x >> 24), (byte)(x >> 16), (byte)(x >> 8), (byte)x,
(byte)(y >> 24), (byte)(y >> 16), (byte)(y >> 8), (byte)y };
return new LLUUID(bytes, 0);
}
public static void ParseFakeParcelID(LLUUID parcelID, out ulong regionHandle, out uint x, out uint y) {
byte[] bytes = parcelID.GetBytes();
regionHandle = Helpers.BytesToUInt64(bytes);
x = Helpers.BytesToUInt(bytes, 8);
// grrr. I'd like to use that code in the next line, but libsl has an off-by-one bug here and returns 0.
//uint y = Helpers.BytesToUInt(bytes, 12);
y = (uint)((bytes[12] << 24) | (bytes[13] << 16) | (bytes[14] << 8) | bytes[15]);
}
} }
} }

View File

@ -229,6 +229,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// private RequestAsset handlerRequestAsset = null; // OnRequestAsset; // private RequestAsset handlerRequestAsset = null; // OnRequestAsset;
private UUIDNameRequest handlerTeleportHomeRequest = null; private UUIDNameRequest handlerTeleportHomeRequest = null;
private RegionHandleRequest handlerRegionHandleRequest = null; // OnRegionHandleRequest
private ParcelInfoRequest handlerParcelInfoRequest = null; // OnParcelInfoRequest
private ScriptAnswer handlerScriptAnswer = null; private ScriptAnswer handlerScriptAnswer = null;
private RequestPayPrice handlerRequestPayPrice = null; private RequestPayPrice handlerRequestPayPrice = null;
private ObjectDeselect handlerObjectDetach = null; private ObjectDeselect handlerObjectDetach = null;
@ -916,6 +919,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest; public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
public event EstateDebugRegionRequest OnEstateDebugRegionRequest; public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest; public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
public event RegionHandleRequest OnRegionHandleRequest;
public event ParcelInfoRequest OnParcelInfoRequest;
public event ScriptReset OnScriptReset; public event ScriptReset OnScriptReset;
public event GetScriptRunning OnGetScriptRunning; public event GetScriptRunning OnGetScriptRunning;
public event SetScriptRunning OnSetScriptRunning; public event SetScriptRunning OnSetScriptRunning;
@ -5296,6 +5301,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Parcel related packets #region Parcel related packets
case PacketType.RegionHandleRequest:
RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
handlerRegionHandleRequest = OnRegionHandleRequest;
if (handlerRegionHandleRequest != null)
{
handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID);
}
break;
case PacketType.ParcelInfoRequest:
ParcelInfoRequestPacket pirPack = (ParcelInfoRequestPacket)Pack;
handlerParcelInfoRequest = OnParcelInfoRequest;
if (handlerParcelInfoRequest != null)
{
handlerParcelInfoRequest(this, pirPack.Data.ParcelID);
}
break;
case PacketType.ParcelAccessListRequest: case PacketType.ParcelAccessListRequest:
ParcelAccessListRequestPacket requestPacket = (ParcelAccessListRequestPacket)Pack; ParcelAccessListRequestPacket requestPacket = (ParcelAccessListRequestPacket)Pack;
@ -6294,5 +6319,45 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
#endregion #endregion
public void SendRegionHandle(LLUUID regionID, ulong handle) {
RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply);
reply.ReplyBlock.RegionID = regionID;
reply.ReplyBlock.RegionHandle = handle;
OutPacket(reply, ThrottleOutPacketType.Land);
}
public void SendParcelInfo(RegionInfo info, LandData land, LLUUID parcelID, uint x, uint y)
{
ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply);
reply.AgentData.AgentID = m_agentId;
reply.Data.ParcelID = parcelID;
reply.Data.OwnerID = land.OwnerID;
reply.Data.Name = Helpers.StringToField(land.Name);
reply.Data.Desc = Helpers.StringToField(land.Description);
reply.Data.ActualArea = land.Area;
reply.Data.BillableArea = land.Area; // TODO: what is this?
// Bit 0: Mature, bit 7: on sale, other bits: no idea
reply.Data.Flags = (byte)(
((land.Flags & (uint)Parcel.ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) +
((land.Flags & (uint)Parcel.ParcelFlags.ForSale) != 0 ? (1 << 7) : 0));
LLVector3 pos = land.UserLocation;
if (pos.Equals(LLVector3.Zero))
{
pos = (land.AABBMax + land.AABBMin) * 0.5f;
}
reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x;
reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y;
reply.Data.GlobalZ = pos.Z;
reply.Data.SimName = Helpers.StringToField(info.RegionName);
reply.Data.SnapshotID = land.SnapshotID;
reply.Data.Dwell = 0; // TODO: not implemented yet
reply.Data.SalePrice = land.SalePrice;
reply.Data.AuctionID = (int)land.AuctionID;
OutPacket(reply, ThrottleOutPacketType.Land);
}
} }
} }

View File

@ -491,5 +491,20 @@ namespace OpenSim.Region.Communications.Local
return false; return false;
} }
public LandData RequestLandData (ulong regionHandle, uint x, uint y)
{
m_log.DebugFormat("[INTERREGION STANDALONE] requests land data in {0}, at {1}, {2}",
regionHandle, x, y);
if (m_regionListeners.ContainsKey(regionHandle))
{
LandData land = m_regionListeners[regionHandle].TriggerGetLandData(x, y);
return land;
}
m_log.Debug("[INTERREGION STANDALONE] didn't find land data locally.");
return null;
}
} }
} }

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Reflection; using System.Reflection;
@ -92,6 +93,7 @@ namespace OpenSim.Region.Communications.OGS1
httpServer.AddXmlRPCHandler("expect_user", ExpectUser); httpServer.AddXmlRPCHandler("expect_user", ExpectUser);
httpServer.AddXmlRPCHandler("logoff_user", LogOffUser); httpServer.AddXmlRPCHandler("logoff_user", LogOffUser);
httpServer.AddXmlRPCHandler("check", PingCheckReply); httpServer.AddXmlRPCHandler("check", PingCheckReply);
httpServer.AddXmlRPCHandler("land_data", LandData);
StartRemoting(); StartRemoting();
} }
@ -1624,5 +1626,104 @@ namespace OpenSim.Region.Communications.OGS1
} }
} }
} }
public LandData RequestLandData (ulong regionHandle, uint x, uint y)
{
m_log.DebugFormat("[OGS1 GRID SERVICES] requests land data in {0}, at {1}, {2}",
regionHandle, x, y);
LandData landData = m_localBackend.RequestLandData(regionHandle, x, y);
if (landData == null)
{
Hashtable hash = new Hashtable();
hash["region_handle"] = regionHandle.ToString();
hash["x"] = x.ToString();
hash["y"] = y.ToString();
IList paramList = new ArrayList();
paramList.Add(hash);
// this might be cached, as we probably requested it just a moment ago...
RegionInfo info = RequestNeighbourInfo(regionHandle);
try
{
XmlRpcRequest request = new XmlRpcRequest("land_data", paramList);
string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
XmlRpcResponse response = request.Send(uri, 10000);
if (response.IsFault)
{
m_log.ErrorFormat("[OGS1 GRID SERVICES] remote call returned an error: {0}", response.FaultString);
}
else
{
hash = (Hashtable)response.Value;
try {
landData = new LandData();
landData.AABBMax = LLVector3.Parse((string)hash["AABBMax"]);
landData.AABBMin = LLVector3.Parse((string)hash["AABBMin"]);
landData.Area = Convert.ToInt32(hash["Area"]);
landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]);
landData.Description = (string)hash["Description"];
landData.Flags = Convert.ToUInt32(hash["Flags"]);
landData.GlobalID = new LLUUID((string)hash["GlobalID"]);
landData.Name = (string)hash["Name"];
landData.OwnerID = new LLUUID((string)hash["OwnerID"]);
landData.SalePrice = Convert.ToInt32(hash["SalePrice"]);
landData.SnapshotID = new LLUUID((string)hash["SnapshotID"]);
landData.UserLocation = LLVector3.Parse((string)hash["UserLocation"]);
m_log.DebugFormat("[OGS1 GRID SERVICES] Got land data for parcel {0}", landData.Name);
}
catch (Exception e)
{
m_log.Error("[OGS1 GRID SERVICES] Got exception while parsing land-data:", e);
}
}
}
catch (Exception e)
{
m_log.ErrorFormat("[OGS1 GRID SERVICES] Couldn't contact region {0}: {1}", regionHandle, e);
}
}
return landData;
}
// Grid Request Processing
/// <summary>
/// Someone asked us about parcel-information
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public XmlRpcResponse LandData(XmlRpcRequest request)
{
Hashtable requestData = (Hashtable)request.Params[0];
ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]);
uint x = Convert.ToUInt32(requestData["x"]);
uint y = Convert.ToUInt32(requestData["y"]);
m_log.DebugFormat("[OGS1 GRID SERVICES]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle);
LandData landData = m_localBackend.RequestLandData(regionHandle, x, y);
Hashtable hash = new Hashtable();
if (landData != null)
{
// for now, only push out the data we need for answering a ParcelInfoReqeust
// FIXME: these Replace calls are necessary as LLVector3.Parse can't parse vectors with spaces in them. Can be removed as soon as we switch to a newer version
hash["AABBMax"] = landData.AABBMax.ToString().Replace(" ", "");
hash["AABBMin"] = landData.AABBMin.ToString().Replace(" ", "");
hash["Area"] = landData.Area.ToString();
hash["AuctionID"] = landData.AuctionID.ToString();
hash["Description"] = landData.Description;
hash["Flags"] = landData.Flags.ToString();
hash["GlobalID"] = landData.GlobalID.ToString();
hash["Name"] = landData.Name;
hash["OwnerID"] = landData.OwnerID.ToString();
hash["SalePrice"] = landData.SalePrice.ToString();
hash["SnapshotID"] = landData.SnapshotID.ToString();
hash["UserLocation"] = landData.UserLocation.ToString().Replace(" ", "");
}
XmlRpcResponse response = new XmlRpcResponse();
response.Value = hash;
return response;
}
} }
} }

View File

@ -26,19 +26,30 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using libsecondlife; using libsecondlife;
using log4net;
using Nini.Config; using Nini.Config;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Communications.Capabilities;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using Axiom.Math; using Axiom.Math;
using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
namespace OpenSim.Region.Environment.Modules.World.Land namespace OpenSim.Region.Environment.Modules.World.Land
{ {
public class LandManagementModule : IRegionModule public class LandManagementModule : IRegionModule
{ {
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string remoteParcelRequestPath = "0009/";
private LandChannel landChannel; private LandChannel landChannel;
private Scene m_scene; private Scene m_scene;
@ -75,6 +86,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land
m_scene.EventManager.OnSetAllowForcefulBan += this.SetAllowedForcefulBans; m_scene.EventManager.OnSetAllowForcefulBan += this.SetAllowedForcefulBans;
m_scene.EventManager.OnRequestParcelPrimCountUpdate += this.PerformParcelPrimCountUpdate; m_scene.EventManager.OnRequestParcelPrimCountUpdate += this.PerformParcelPrimCountUpdate;
m_scene.EventManager.OnParcelPrimCountTainted += this.SetPrimsTainted; m_scene.EventManager.OnParcelPrimCountTainted += this.SetPrimsTainted;
m_scene.EventManager.OnRegisterCaps += this.OnRegisterCaps;
lock (m_scene) lock (m_scene)
{ {
@ -95,7 +107,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land
client.OnParcelAccessListUpdateRequest += new ParcelAccessListUpdateRequest(handleParcelAccessUpdateRequest); client.OnParcelAccessListUpdateRequest += new ParcelAccessListUpdateRequest(handleParcelAccessUpdateRequest);
client.OnParcelAbandonRequest += new ParcelAbandonRequest(handleParcelAbandonRequest); client.OnParcelAbandonRequest += new ParcelAbandonRequest(handleParcelAbandonRequest);
client.OnParcelReclaim += new ParcelReclaim(handleParcelReclaim); client.OnParcelReclaim += new ParcelReclaim(handleParcelReclaim);
client.OnParcelInfoRequest += new ParcelInfoRequest(handleParcelInfo);
if (m_scene.Entities.ContainsKey(client.AgentId)) if (m_scene.Entities.ContainsKey(client.AgentId))
{ {
SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true); SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true);
@ -1084,6 +1096,112 @@ namespace OpenSim.Region.Environment.Modules.World.Land
public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
{ {
} }
#region CAPS handler
private void OnRegisterCaps(LLUUID agentID, Caps caps)
{
string capsBase = "/CAPS/" + caps.CapsObjectPath;
caps.RegisterHandler("RemoteParcelRequest",
new RestStreamHandler("POST", capsBase + remoteParcelRequestPath,
delegate(string request, string path, string param,
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
return RemoteParcelRequest(request, path, param, agentID, caps);
}));
}
// we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the
// "real" parcelID, because we wouldn't be able to map that to the region the parcel belongs to.
// So, we create a "fake" parcelID by using the regionHandle (64 bit), and the local (integer) x
// and y coordinate (each 8 bit), encoded in a LLUUID (128 bit).
//
// Request format:
// <llsd>
// <map>
// <key>location</key>
// <array>
// <real>1.23</real>
// <real>45..6</real>
// <real>78.9</real>
// </array>
// <key>region_id</key>
// <uuid>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</uuid>
// </map>
// </llsd>
private string RemoteParcelRequest(string request, string path, string param, LLUUID agentID, Caps caps)
{
LLUUID parcelID = LLUUID.Zero;
try
{
Hashtable hash = new Hashtable();
hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request));
if(hash.ContainsKey("region_id") && hash.ContainsKey("location"))
{
LLUUID regionID = (LLUUID)hash["region_id"];
ArrayList list = (ArrayList)hash["location"];
uint x = (uint)(double)list[0];
uint y = (uint)(double)list[1];
if(hash.ContainsKey("region_handle"))
{
// if you do a "About Landmark" on a landmark a second time, the viewer sends the
// region_handle it got earlier via RegionHandleRequest
ulong regionHandle = Helpers.BytesToUInt64((byte[])hash["region_handle"]);
parcelID = Util.BuildFakeParcelID(regionHandle, x, y);
}
else if(regionID == m_scene.RegionInfo.RegionID)
{
// a parcel request for a local parcel => no need to query the grid
parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y);
}
else
{
// a parcel request for a parcel in another region. Ask the grid about the region
RegionInfo info = m_scene.CommsManager.GridService.RequestNeighbourInfo(regionID);
if(info != null) parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y);
}
}
}
catch (LLSD.LLSDParseException e)
{
m_log.ErrorFormat("[LAND] Fetch error: {0}", e.Message);
m_log.ErrorFormat("[LAND] ... in request {0}", request);
}
catch(InvalidCastException)
{
m_log.ErrorFormat("[LAND] Wrong type in request {0}", request);
}
LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse();
response.parcel_id = parcelID;
m_log.DebugFormat("[LAND] got parcelID {0}", parcelID);
return LLSDHelpers.SerialiseLLSDReply(response);
}
#endregion
private void handleParcelInfo(IClientAPI remoteClient, LLUUID parcelID)
{
if(parcelID == LLUUID.Zero) return;
// assume we've got the parcelID we just computed in RemoteParcelRequest
ulong regionHandle;
uint x, y;
Util.ParseFakeParcelID(parcelID, out regionHandle, out x, out y);
m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}", regionHandle, x, y);
LandData landData;
if(regionHandle == m_scene.RegionInfo.RegionHandle) landData = this.GetLandObject(x, y).landData;
else landData = m_scene.CommsManager.GridService.RequestLandData(regionHandle, x, y);
if(landData != null)
{
// we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
m_log.Debug("[LAND] got parcelinfo; sending");
remoteClient.SendParcelInfo(m_scene.RegionInfo, landData, parcelID, x, y);
}
else m_log.Debug("[LAND] got no parcelinfo; not sending");
}
} }
} }

View File

@ -302,6 +302,10 @@ namespace OpenSim.Region.Environment.Modules.World.NPC
public event UpdateVector OnAutoPilotGo; public event UpdateVector OnAutoPilotGo;
public event TerrainUnacked OnUnackedTerrain; public event TerrainUnacked OnUnackedTerrain;
public event RegionHandleRequest OnRegionHandleRequest;
public event ParcelInfoRequest OnParcelInfoRequest;
#pragma warning restore 67 #pragma warning restore 67
#endregion #endregion
@ -832,5 +836,13 @@ namespace OpenSim.Region.Environment.Modules.World.NPC
public void SendClearFollowCamProperties (LLUUID objectID) public void SendClearFollowCamProperties (LLUUID objectID)
{ {
} }
public void SendRegionHandle (LLUUID regoinID, ulong handle)
{
}
public void SendParcelInfo (RegionInfo info, LandData land, LLUUID parcelID, uint x, uint y)
{
}
} }
} }

View File

@ -2170,6 +2170,8 @@ namespace OpenSim.Region.Environment.Scenes
client.OnScriptReset += ProcessScriptReset; client.OnScriptReset += ProcessScriptReset;
client.OnGetScriptRunning += GetScriptRunning; client.OnGetScriptRunning += GetScriptRunning;
client.OnSetScriptRunning += SetScriptRunning; client.OnSetScriptRunning += SetScriptRunning;
client.OnRegionHandleRequest += RegionHandleRequest;
client.OnUnackedTerrain += TerrainUnAcked; client.OnUnackedTerrain += TerrainUnAcked;
@ -2502,6 +2504,7 @@ namespace OpenSim.Region.Environment.Scenes
m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
m_sceneGridService.KillObject += SendKillObject; m_sceneGridService.KillObject += SendKillObject;
m_sceneGridService.OnGetLandData += GetLandData;
} }
/// <summary> /// <summary>
@ -2518,6 +2521,7 @@ namespace OpenSim.Region.Environment.Scenes
m_sceneGridService.OnExpectUser -= NewUserConnection; m_sceneGridService.OnExpectUser -= NewUserConnection;
m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing; m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
m_sceneGridService.OnCloseAgentConnection -= CloseConnection; m_sceneGridService.OnCloseAgentConnection -= CloseConnection;
m_sceneGridService.OnGetLandData -= GetLandData;
m_sceneGridService.Close(); m_sceneGridService.Close();
} }
@ -3436,6 +3440,12 @@ namespace OpenSim.Region.Environment.Scenes
return LandChannel.GetLandObject(x, y).landData; return LandChannel.GetLandObject(x, y).landData;
} }
public LandData GetLandData(uint x, uint y)
{
m_log.DebugFormat("[SCENE] returning land for {0},{1}", x, y);
return LandChannel.GetLandObject((int)x, (int)y).landData;
}
public void SetLandMusicURL(float x, float y, string url) public void SetLandMusicURL(float x, float y, string url)
{ {
ILandObject land = LandChannel.GetLandObject(x, y); ILandObject land = LandChannel.GetLandObject(x, y);
@ -3833,6 +3843,14 @@ namespace OpenSim.Region.Environment.Scenes
// client.SendParcelMediaCommand((uint)(4), ParcelMediaCommandEnum.Play, 0); // client.SendParcelMediaCommand((uint)(4), ParcelMediaCommandEnum.Play, 0);
// }); // });
} }
public void RegionHandleRequest(IClientAPI client, LLUUID regionID)
{
RegionInfo info;
if(regionID == RegionInfo.RegionID) info = RegionInfo;
else info = CommsManager.GridService.RequestNeighbourInfo(regionID);
if(info != null) client.SendRegionHandle(regionID, info.RegionHandle);
}
public void TerrainUnAcked(IClientAPI client, int patchX, int patchY) public void TerrainUnAcked(IClientAPI client, int patchX, int patchY)

View File

@ -59,7 +59,8 @@ namespace OpenSim.Region.Environment.Scenes
public event ChildAgentUpdate OnChildAgentUpdate; public event ChildAgentUpdate OnChildAgentUpdate;
public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar;
public event LogOffUser OnLogOffUser; public event LogOffUser OnLogOffUser;
public event GetLandData OnGetLandData;
private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion;
private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser;
private ExpectPrimDelegate handlerExpectPrim = null; // OnExpectPrim; private ExpectPrimDelegate handlerExpectPrim = null; // OnExpectPrim;
@ -69,6 +70,7 @@ namespace OpenSim.Region.Environment.Scenes
private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate;
private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar; private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar;
private LogOffUser handlerLogOffUser = null; private LogOffUser handlerLogOffUser = null;
private GetLandData handlerGetLandData = null; // OnGetLandData
public KillObjectDelegate KillObject; public KillObjectDelegate KillObject;
public string _debugRegionName = String.Empty; public string _debugRegionName = String.Empty;
@ -108,6 +110,7 @@ namespace OpenSim.Region.Environment.Scenes
regionCommsHost.OnRegionUp += newRegionUp; regionCommsHost.OnRegionUp += newRegionUp;
regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate; regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate;
regionCommsHost.OnLogOffUser += GridLogOffUser; regionCommsHost.OnLogOffUser += GridLogOffUser;
regionCommsHost.OnGetLandData += FetchLandData;
} }
else else
{ {
@ -131,6 +134,7 @@ namespace OpenSim.Region.Environment.Scenes
regionCommsHost.OnExpectPrim -= IncomingPrimCrossing; regionCommsHost.OnExpectPrim -= IncomingPrimCrossing;
regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing; regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing;
regionCommsHost.OnCloseAgentConnection -= CloseConnection; regionCommsHost.OnCloseAgentConnection -= CloseConnection;
regionCommsHost.OnGetLandData -= FetchLandData;
m_commsProvider.GridService.DeregisterRegion(m_regionInfo); m_commsProvider.GridService.DeregisterRegion(m_regionInfo);
regionCommsHost = null; regionCommsHost = null;
} }
@ -227,6 +231,16 @@ namespace OpenSim.Region.Environment.Scenes
return false; return false;
} }
protected LandData FetchLandData(uint x, uint y)
{
handlerGetLandData = OnGetLandData;
if (handlerGetLandData != null)
{
return handlerGetLandData(x, y);
}
return null;
}
#endregion #endregion
#region Inform Client of Neighbours #region Inform Client of Neighbours

View File

@ -204,6 +204,9 @@ namespace OpenSim.Region.Examples.SimpleModule
public event TerrainUnacked OnUnackedTerrain; public event TerrainUnacked OnUnackedTerrain;
public event RegionHandleRequest OnRegionHandleRequest;
public event ParcelInfoRequest OnParcelInfoRequest;
#pragma warning restore 67 #pragma warning restore 67
private LLUUID myID = LLUUID.Random(); private LLUUID myID = LLUUID.Random();
@ -832,5 +835,13 @@ namespace OpenSim.Region.Examples.SimpleModule
public void SendClearFollowCamProperties (LLUUID objectID) public void SendClearFollowCamProperties (LLUUID objectID)
{ {
} }
public void SendRegionHandle (LLUUID regoinID, ulong handle)
{
}
public void SendParcelInfo (RegionInfo info, LandData land, LLUUID parcelID, uint x, uint y)
{
}
} }
} }