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
parent
f191f38a3e
commit
d9cc908471
|
@ -86,11 +86,13 @@ namespace OpenSim.Framework.Communications.Capabilities
|
|||
private static readonly string m_notecardTaskUpdatePath = "0005/";
|
||||
// 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.
|
||||
// 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_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
|
||||
|
||||
//private string eventQueue = "0100/";
|
||||
private BaseHttpServer m_httpListener;
|
||||
private LLUUID m_agentID;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,5 +57,7 @@ namespace OpenSim.Framework.Communications
|
|||
RegionInfo RequestClosestRegion(string regionName);
|
||||
Dictionary<string, string> GetGridSettings();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 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 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 GetScriptRunning(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID);
|
||||
public delegate void SetScriptRunning(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID, bool running);
|
||||
|
@ -498,6 +501,9 @@ namespace OpenSim.Framework
|
|||
event EstateDebugRegionRequest OnEstateDebugRegionRequest;
|
||||
event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
|
||||
event UUIDNameRequest OnUUIDGroupNameRequest;
|
||||
|
||||
event RegionHandleRequest OnRegionHandleRequest;
|
||||
event ParcelInfoRequest OnParcelInfoRequest;
|
||||
|
||||
event RequestObjectPropertiesFamily OnObjectGroupRequest;
|
||||
event ScriptReset OnScriptReset;
|
||||
|
@ -721,5 +727,8 @@ namespace OpenSim.Framework
|
|||
|
||||
void SendSetFollowCamProperties(LLUUID objectID, SortedDictionary<int, float> parameters);
|
||||
void SendClearFollowCamProperties(LLUUID objectID);
|
||||
|
||||
void SendRegionHandle(LLUUID regoinID, ulong handle);
|
||||
void SendParcelInfo(RegionInfo info, LandData land, LLUUID parcelID, uint x, uint y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ namespace OpenSim.Framework
|
|||
|
||||
public delegate void LogOffUser(ulong regionHandle, LLUUID agentID, LLUUID regionSecret, string message);
|
||||
|
||||
public delegate LandData GetLandData(uint x, uint y);
|
||||
|
||||
public interface IRegionCommsListener
|
||||
{
|
||||
event ExpectUserDelegate OnExpectUser;
|
||||
|
@ -66,5 +68,6 @@ namespace OpenSim.Framework
|
|||
event RegionUp OnRegionUp;
|
||||
event ChildAgentUpdate OnChildAgentUpdate;
|
||||
event LogOffUser OnLogOffUser;
|
||||
event GetLandData OnGetLandData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,8 @@ namespace OpenSim.Framework
|
|||
private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion;
|
||||
private RegionUp handlerRegionUp = null; // OnRegionUp;
|
||||
private LogOffUser handlerLogOffUser = null;
|
||||
|
||||
private GetLandData handlerGetLandData = null;
|
||||
|
||||
#region IRegionCommsListener Members
|
||||
|
||||
public event ExpectUserDelegate OnExpectUser;
|
||||
|
@ -61,6 +62,7 @@ namespace OpenSim.Framework
|
|||
public event RegionUp OnRegionUp;
|
||||
public event ChildAgentUpdate OnChildAgentUpdate;
|
||||
public event LogOffUser OnLogOffUser;
|
||||
public event GetLandData OnGetLandData;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -226,5 +228,14 @@ namespace OpenSim.Framework
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public LandData TriggerGetLandData(uint x, uint y)
|
||||
{
|
||||
handlerGetLandData = OnGetLandData;
|
||||
if (handlerGetLandData != null)
|
||||
return handlerGetLandData(x, y);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -716,5 +716,24 @@ namespace OpenSim.Framework
|
|||
XmlRpcRequest client = new XmlRpcRequest(methodName, args);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,6 +229,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// private RequestAsset handlerRequestAsset = null; // OnRequestAsset;
|
||||
private UUIDNameRequest handlerTeleportHomeRequest = null;
|
||||
|
||||
private RegionHandleRequest handlerRegionHandleRequest = null; // OnRegionHandleRequest
|
||||
private ParcelInfoRequest handlerParcelInfoRequest = null; // OnParcelInfoRequest
|
||||
|
||||
private ScriptAnswer handlerScriptAnswer = null;
|
||||
private RequestPayPrice handlerRequestPayPrice = null;
|
||||
private ObjectDeselect handlerObjectDetach = null;
|
||||
|
@ -916,6 +919,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
|
||||
public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
|
||||
public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
|
||||
public event RegionHandleRequest OnRegionHandleRequest;
|
||||
public event ParcelInfoRequest OnParcelInfoRequest;
|
||||
public event ScriptReset OnScriptReset;
|
||||
public event GetScriptRunning OnGetScriptRunning;
|
||||
public event SetScriptRunning OnSetScriptRunning;
|
||||
|
@ -5296,6 +5301,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
#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:
|
||||
ParcelAccessListRequestPacket requestPacket = (ParcelAccessListRequestPacket)Pack;
|
||||
|
||||
|
@ -6294,5 +6319,45 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -491,5 +491,20 @@ namespace OpenSim.Region.Communications.Local
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
|
@ -92,6 +93,7 @@ namespace OpenSim.Region.Communications.OGS1
|
|||
httpServer.AddXmlRPCHandler("expect_user", ExpectUser);
|
||||
httpServer.AddXmlRPCHandler("logoff_user", LogOffUser);
|
||||
httpServer.AddXmlRPCHandler("check", PingCheckReply);
|
||||
httpServer.AddXmlRPCHandler("land_data", LandData);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,19 +26,30 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Communications.Capabilities;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using Axiom.Math;
|
||||
using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Land
|
||||
{
|
||||
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 Scene m_scene;
|
||||
|
||||
|
@ -75,6 +86,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land
|
|||
m_scene.EventManager.OnSetAllowForcefulBan += this.SetAllowedForcefulBans;
|
||||
m_scene.EventManager.OnRequestParcelPrimCountUpdate += this.PerformParcelPrimCountUpdate;
|
||||
m_scene.EventManager.OnParcelPrimCountTainted += this.SetPrimsTainted;
|
||||
m_scene.EventManager.OnRegisterCaps += this.OnRegisterCaps;
|
||||
|
||||
lock (m_scene)
|
||||
{
|
||||
|
@ -95,7 +107,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land
|
|||
client.OnParcelAccessListUpdateRequest += new ParcelAccessListUpdateRequest(handleParcelAccessUpdateRequest);
|
||||
client.OnParcelAbandonRequest += new ParcelAbandonRequest(handleParcelAbandonRequest);
|
||||
client.OnParcelReclaim += new ParcelReclaim(handleParcelReclaim);
|
||||
|
||||
client.OnParcelInfoRequest += new ParcelInfoRequest(handleParcelInfo);
|
||||
if (m_scene.Entities.ContainsKey(client.AgentId))
|
||||
{
|
||||
SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true);
|
||||
|
@ -1084,6 +1096,112 @@ namespace OpenSim.Region.Environment.Modules.World.Land
|
|||
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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -302,6 +302,10 @@ namespace OpenSim.Region.Environment.Modules.World.NPC
|
|||
public event UpdateVector OnAutoPilotGo;
|
||||
|
||||
public event TerrainUnacked OnUnackedTerrain;
|
||||
|
||||
public event RegionHandleRequest OnRegionHandleRequest;
|
||||
public event ParcelInfoRequest OnParcelInfoRequest;
|
||||
|
||||
#pragma warning restore 67
|
||||
|
||||
#endregion
|
||||
|
@ -832,5 +836,13 @@ namespace OpenSim.Region.Environment.Modules.World.NPC
|
|||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2170,6 +2170,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
client.OnScriptReset += ProcessScriptReset;
|
||||
client.OnGetScriptRunning += GetScriptRunning;
|
||||
client.OnSetScriptRunning += SetScriptRunning;
|
||||
|
||||
client.OnRegionHandleRequest += RegionHandleRequest;
|
||||
|
||||
client.OnUnackedTerrain += TerrainUnAcked;
|
||||
|
||||
|
@ -2502,6 +2504,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
|
||||
m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
|
||||
m_sceneGridService.KillObject += SendKillObject;
|
||||
m_sceneGridService.OnGetLandData += GetLandData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2518,6 +2521,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_sceneGridService.OnExpectUser -= NewUserConnection;
|
||||
m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
|
||||
m_sceneGridService.OnCloseAgentConnection -= CloseConnection;
|
||||
m_sceneGridService.OnGetLandData -= GetLandData;
|
||||
|
||||
m_sceneGridService.Close();
|
||||
}
|
||||
|
@ -3436,6 +3440,12 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
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)
|
||||
{
|
||||
ILandObject land = LandChannel.GetLandObject(x, y);
|
||||
|
@ -3833,6 +3843,14 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
// 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)
|
||||
|
|
|
@ -59,7 +59,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public event ChildAgentUpdate OnChildAgentUpdate;
|
||||
public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar;
|
||||
public event LogOffUser OnLogOffUser;
|
||||
|
||||
public event GetLandData OnGetLandData;
|
||||
|
||||
private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion;
|
||||
private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser;
|
||||
private ExpectPrimDelegate handlerExpectPrim = null; // OnExpectPrim;
|
||||
|
@ -69,6 +70,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate;
|
||||
private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar;
|
||||
private LogOffUser handlerLogOffUser = null;
|
||||
private GetLandData handlerGetLandData = null; // OnGetLandData
|
||||
|
||||
public KillObjectDelegate KillObject;
|
||||
public string _debugRegionName = String.Empty;
|
||||
|
@ -108,6 +110,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
regionCommsHost.OnRegionUp += newRegionUp;
|
||||
regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate;
|
||||
regionCommsHost.OnLogOffUser += GridLogOffUser;
|
||||
regionCommsHost.OnGetLandData += FetchLandData;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -131,6 +134,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
regionCommsHost.OnExpectPrim -= IncomingPrimCrossing;
|
||||
regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing;
|
||||
regionCommsHost.OnCloseAgentConnection -= CloseConnection;
|
||||
regionCommsHost.OnGetLandData -= FetchLandData;
|
||||
m_commsProvider.GridService.DeregisterRegion(m_regionInfo);
|
||||
regionCommsHost = null;
|
||||
}
|
||||
|
@ -227,6 +231,16 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
return false;
|
||||
}
|
||||
|
||||
protected LandData FetchLandData(uint x, uint y)
|
||||
{
|
||||
handlerGetLandData = OnGetLandData;
|
||||
if (handlerGetLandData != null)
|
||||
{
|
||||
return handlerGetLandData(x, y);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inform Client of Neighbours
|
||||
|
|
|
@ -204,6 +204,9 @@ namespace OpenSim.Region.Examples.SimpleModule
|
|||
|
||||
public event TerrainUnacked OnUnackedTerrain;
|
||||
|
||||
public event RegionHandleRequest OnRegionHandleRequest;
|
||||
public event ParcelInfoRequest OnParcelInfoRequest;
|
||||
|
||||
#pragma warning restore 67
|
||||
|
||||
private LLUUID myID = LLUUID.Random();
|
||||
|
@ -832,5 +835,13 @@ namespace OpenSim.Region.Examples.SimpleModule
|
|||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue